我在下面的代码中想知道为什么i和j的结果是不同的。对于我的直觉,b也指向了值为4的char的地址。为什么i和j的结果不同
char c='4';
const char *b;
int i,j;
i=atoi(string(1,c).c_str());
b=string(1,c).c_str();
j=atoi(b);
cout<<i<<" "<<j<<endl;
答案 0 :(得分:5)
b=string(1,c).c_str();
b
指向在此声明后销毁的临时对象。它实际上有未定义的行为。
将char转换为int的简短方法是:
int i = c- '0';
答案 1 :(得分:2)
在某些体系结构(os,编译器,stl实现)上,代码按预期生成“4 4”。试一试here。
问题是代码依赖于未定义的行为,因为它使用了被销毁的对象返回的指针。
写作时
b = string(1,c).c_str();
您正在创建一个临时对象,并要求它指向一个字符数组的指针。您将此指针指定给b,然后销毁临时对象(它拥有现在指向的内存b)。假设库是“理智的”,那么在字符串销毁期间将释放这样的内存。因此,通过指针b访问内存是未定义的行为。
当然,你不应该依赖未定义的行为,即使它在某些情况下“有效”。
答案 2 :(得分:2)
b = string(1,c).c_str();
这会在表达式之后创建一个超出范围的临时string
。问题是c_str()
返回的指针只有在生命中调用它的字符串时才有效,并且没有调用非const函数。
如果您沿着这条路线前进,则需要确保在致电string
时原始atoi
有效。
std::string s(1,c);
b = s.c_str();
j = atoi(b);
s.clear(); // b is no longer valid now!
可替换地:
j = atoi(string(1,c).c_str());