下面的代码安全吗?编写类似于此的代码可能很诱人:
#include <map>
const std::map<const char*, int> m = {
{"text1", 1},
{"text2", 2}
};
int main () {
volatile const auto a = m.at("text1");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
该映射仅用于字符串文字.
我认为它是完全合法的并且似乎正在工作,但是我从未看到保证在两个不同的地方使用的文字指针是相同的.我无法让编译器为具有相同内容的文字生成两个单独的指针,所以我开始怀疑这个假设是多么坚定.
我只对具有相同内容的文字是否可以有不同的指针感兴趣.或者更正式的,上面的代码可以除外吗?
我知道有一种编写代码的方法可以确保它有效,我认为上面的方法很危险,因为编译器可以决定为文字分配两个不同的存储,特别是如果它们放在不同的翻译单元中.我对吗?
我的代码是:
#include <stdio.h>
#include <string.h>
void main()
{
char string[10];
int A = -73;
unsigned int B = 31337;
strcpy(string, "sample");
// printing with different formats
printf("[A] Dec: %d, Hex: %x, Unsigned: %u\n", A,A,A);
printf("[B] Dec: %d, Hex: %x, Unsigned: %u\n", B,B,B);
printf("[field width on B] 3: '%3u', 10: '%10u', '%08u'\n", B,B,B);
// Example of unary address operator (dereferencing) and a %x
// format string
printf("variable A is at address: %08x\n", &A);
Run Code Online (Sandbox Code Playgroud)
我在linux mint中使用终端编译,当我尝试使用gcc编译时,我收到以下错误消息:
basicStringFormatting.c: In function ‘main’:
basicStringFormatting.c:18:2: warning: …Run Code Online (Sandbox Code Playgroud) 我知道为了比较C中的两个字符串,您需要使用该strcmp()函数.但我试图将两个字符串与==运算符进行比较,并且它有效.我不知道如何,因为它只是比较两个字符串的地址.如果字符串不同,它应该不起作用.但后来我打印了字符串的地址:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char* str1 = "First";
char* str2 = "Second";
char* str3 = "First";
printf("%p %p %p", str1, str2, str3);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是:
00403024 0040302A 00403024
Process returned 0 (0x0) execution time : 0.109 s
Press any key to continue.
Run Code Online (Sandbox Code Playgroud)
怎么可能str1和str3具有相同的地址?它们可能包含相同的字符串,但它们不是同一个变量.
我正在开发一个使用无序容器的(C++)库.这些需要一个哈希(通常是模板结构的特化std::hash),用于它们存储的元素类型.在我的例子中,这些元素是封装字符串文字的类,类似于本页底部conststr的示例.STL为常量char指针提供了一个特化,但是,它只计算指针,如下所述,在'Notes'部分中:
C字符串没有专门化.
std::hash<const char*>产生指针值的哈希值(内存地址),它不检查任何字符数组的内容.
虽然这很快(或者我认为),但是C++标准并不能保证在同一地址存储多个相等的字符串文字,如本问题所述.如果不是,则不符合哈希的第一个条件:
对于两个相等的参数k1和k2,
std::hash<Key>()(k1) == std::hash<Key>()(k2)
如果给出上述保证,我想使用提供的特化选择性地计算散列,否则我想使用其他算法.虽然回过头来询问那些包含我的标题或构建我的库的人来定义一个特定的宏是可行的,但是一个实现定义的更好.
在任何C++实现中是否有任何宏,但主要是g ++和clang,其定义保证在同一地址存储几个相等的字符串文字?
一个例子:
#ifdef __GXX_SAME_STRING_LITERALS_SAME_ADDRESS__
const char str1[] = "abc";
const char str2[] = "abc";
assert( str1 == str2 );
#endif
Run Code Online (Sandbox Code Playgroud) I'd like to ask if is it portable to rely on string literal address across translation units? I.e:
A given file foo.c has a reference to a string literal "I'm a literal!", is it correct and portable to rely that in other given file, bar.c in instance, that the same string literal "I'm a literal!" will have the same memory address? Considering that each file will be translated to a individual .o file.
For better illustration, follows an …
我有这个代码:
char *name = "George"
if(name == "George")
printf("It's George")
Run Code Online (Sandbox Code Playgroud)
我认为c字符串无法与==sign 进行比较,我必须使用strcmp.由于未知原因,当我使用gcc(版本4.7.3)编译时,此代码有效.我认为这是错误的,因为它就像比较指针,所以我在谷歌搜索,很多人说这是错误的,比较==不能做.那么为什么这种比较方法有效?
int *x = 3;
int *y = 3;
if (x == y) "this statement evaluates to true" (pointer equality statement)
if (*x == *y) "this statement evaluates to true"
Run Code Online (Sandbox Code Playgroud)
是指针等式语句变为真的原因,仅仅是因为COMPILER看到两个"静态"数字"3"并且说,嘿指向同一个地方?或者一般来说整数有一些魔力.
显然,冗余引用整数指针与未解除引用相同(在本例中).
我已经看到了一些与字符串相关的问题的例子(两个指针的地址是相同的),但是想要澄清它.
我有一个问题,我看到两个指针的地址在这里是相同的(两个指针的地址是相同的),也由蓝色月亮回答.这让我更加怀疑.由于两个指针都有相同的地址,我想改变其中一个指针的值,期望值也会在其他指针中改变(因为它们具有相同的地址).但它给出了分段错误.我在下面的代码中显示它.
#include<stdio.h>
#include<string.h>
int main()
{
char * p = "abc";
char * p1 = "abc";
printf("%d\n %d\n", (void *)p, (void *)p1);
printf("%s\n %s\n", p, p1);
*p = 'b';
printf("%d\n %d\n", p, p1);
printf("%s\n %s\n", p, p1);
}
Run Code Online (Sandbox Code Playgroud) 以下是我设置关联对象的方法:
objc_setAssociatedObject(navigationItem, "rightButton", leftButtonView, OBJC_ASSOCIATION_RETAIN);
Run Code Online (Sandbox Code Playgroud)
这是我如何得到它:
UIButton *favoriteButton = (UIButton *)objc_getAssociatedObject(self.navigationItem, "rightButton");
Run Code Online (Sandbox Code Playgroud)
UIButton两个实例中的对象都是一个,我#import "objc/runtime.h"在两个类中都有.
事情是,它曾经工作,但现在由于某种原因它返回null.有任何想法吗?
编辑
我通过传递navigationItem作为参数在另一个类中设置关联对象:
+ (void)setNavigationBarTitle:(NSString *)title
andLeftButton:(NSString *)leftButtonTitle
withSelector:(SEL)leftSelector
andRightButton:(NSString *)rightButtonTitle
withSelector:(SEL)rightSelector
andTarget:(id)target
forNavigationItem:(UINavigationItem *)navigationItem;
Run Code Online (Sandbox Code Playgroud)
我在我的实用程序类中使用这个方便方法为我的应用程序中的每个新视图控制器设置导航栏.在创建导航栏按钮时,我将它们与导航项相关联 - 我在问题中的第一行代码.
有人可以帮我理解这个吗?
我已经创建了一个char字符串的映射作为键,而int作为来自二维char数组的值.我看到地图中插入了重复的条目!
为了进一步测试,我向地图添加了两个相同值的char字符串(也在代码中,注释了),并且只添加了其中一个.
void countstr(char words[][NUM_OF_STR])
{
map<char*, int> mwords;
cout<<"ORIG"<<endl;
for(int i = 0; i < NUM_OF_STR; i ++)
{
cout<<words[i]<<endl;
mwords.insert(pair<char*, int>(words[i], 0));
cout<<mwords.size()<<endl;
}
map<char*, int>::iterator itr;
cout<<endl<<"MAP"<<endl;
for(auto i = mwords.begin(); i != mwords.end(); i ++)
{
cout<<i->first<<"\t"<<i->second<<endl;
}
return;
}
int main()
{
char words[NUM_OF_STR][5] = { "abc", "pqr", "xyz", "abc", "pqr" };
/*map<char*, int> mwords;
mwords.insert(pair<char*, int>("abc", 1));
cout<<mwords.size()<<endl;
mwords.insert(pair<char*, int>("abc", 2));
cout<<mwords.size()<<endl;*/
countstr(words);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
ORIG
abc
1
pqr
2
xyz …Run Code Online (Sandbox Code Playgroud) 我想在C中获取字符串常量的地址.
char * const MYCONST = "StringString";
Run Code Online (Sandbox Code Playgroud)
据我所知,consts被"保存"在内存的文本/代码段中.当我试图获取MYCONSt中第一个元素的地址时:
printf("%p\n",&(MYCONST));
Run Code Online (Sandbox Code Playgroud)
结果我得到0x7fff15342e28,它在堆栈中而不在文本/代码段中.任何人都可以帮我在C中获取字符串常量的地址吗?
//编辑到目前为止我找不到正确的答案:我写的时候
char * const MYCONST1 = "StringString";
printf("Address of MYCONST1: %p\n",MYCONST1);
char * const MYCONST2 = "StringString";
printf("Address of MYCONST2: %p\n",(void*)MYCONST2);
Run Code Online (Sandbox Code Playgroud)
这是输出:
MYCONST1的地址:0x400b91
MYCONST2的地址:0x400b91
但它们应该有不同的地址,因为它们是不同的常量.任何人都可以解释我,结果的长度为7,而不是0x7fffa5dd398c,就像一个locale变量.
谢谢!