从类型char到int的转换会产生不同的结果
transform from type char to int produce different result
在下面的代码中,我想知道为什么I和j的结果不同。根据我的直觉,b还指向了一个值为4的字符的地址。为什么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;
b=string(1,c).c_str();
b
指向一个临时对象,该对象在该语句之后被销毁。它实际上有未定义的行为。
将char转换为int的一个简单方法是:
int i = c- '0';
b = string(1,c).c_str();
这将在表达式之后创建一个超出范围的临时string
。问题是,c_str()
返回的指针只有在调用它的字符串存在并且没有调用任何非常数函数的情况下才有效。
如果你按照这种方式行事,那么在调用atoi
时,你需要确保原始的string
是有效的。
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());
在某些体系结构(操作系统、编译器、stl实现)上,代码会按预期生成"4 4"。在这里试试。
问题是,代码依赖于未定义的行为,因为它使用了一个被破坏的对象返回的指针。
当你写
b = string(1,c).c_str();
您正在创建一个临时对象,并要求它提供一个指向字符数组的指针。您将此指针分配给b,然后临时对象(拥有b现在指向的内存)将被销毁。假设库是"正常的",那么在字符串销毁过程中,这样的内存将被释放。因此,经由指针b访问存储器是未定义的行为。
当然,你不应该依赖未定义的行为,即使它在某些情况下"有效"。
相关文章:
- 为什么在逗号分隔符上下文中将预增量的结果强制转换为void
- 尝试将字符串/字符转换为整数会产生意外结果
- Static_cast转换为错误的数据类型,但结果仍然正确?
- 是否可以将无符号 int 的最大值转换为 int 并将结果转换为 -1?
- 使用 sprintf 和 %g 将双精度转换为字符串的意外结果
- 字符到int8_t转换会产生意想不到的结果?
- 将字符串强制转换为GUID并不能得到正确的结果
- 转换为标准时,Clang和GCC中的不同结果::可选<T>
- 如何将 xt::sum 表达式结果转换为整数
- 将函数的地址转换为UINTPTR_T给我不正确的结果
- std::reduce 似乎将结果转换为整数
- 硬编码字符串与强制转换为 PUCHAR 并打印到控制台时从控制台读取的字符串的结果不同
- 为什么在 C# 中将 ushort 端口号从 hton 转换为 ntohs 会给出不同的结果
- time_t提高日期转换,给出不正确的结果
- 将词法强制转换双倍提升为字符串,给出无效结果
- 尝试将二进制数组转换为十六进制C++然后打印结果
- 在C++中将 sqlite 结果转换为 std::string
- 将inet_ntop的结果转换为字符串
- 无法将std::bind的结果转换为std::函数
- 在使用/Wp64进行编译时,如何在不发出警告的情况下将strlen的结果转换为int