最近,我对指针感到好奇,而且我不明白为什么以下命令不起作用。
我的想法是创建一个变量,说出它的地址(十进制),要求用户将其输入回来,并将其作为指向前一个变量的指针的地址。最后,两个变量应具有相同的值。
最后一个指针应该指向一个错误的内存地址,因为它存在段错误,但是当我打印指针的地址时,它们是相同的!
#include <iostream>
int main() {
int temp = 0;
printf("Temporary integer addr 0x%x (dec %d)\n", &temp, &temp);
int input = -1;
printf("Give me an address to read (in dec)\n");
std::cin >> input;
printf("You chose the number %d (hex 0x%x)\n", input, input);
int* intPtr = (int*)input;
int* tempPtr = &temp;
if (intPtr == tempPtr) {
printf("It works, they are equal!\n");
} else {
printf("Expected: 0x%x got 0x%x\n", tempPtr, intPtr);
printf("Expected value: 0x%d got 0x%d", temp, *intPtr); // segfaults
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是控制台输出
Main function addr 0xb0ddf7d0 (dec -1327630384)
Temporary integer addr 0xb0ddf7c8 (dec -1327630392)
Give me an address to read (in dec)
-1327630392
You chose the number -1327630392 (hex 0xb0ddf7c8)
Expected: 0xb0ddf7c8 got 0xb0ddf7c8
Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
Run Code Online (Sandbox Code Playgroud)
怎么了 如何创建一个指向用户输入地址的指针?我在g ++(GCC)8.2.1 20181127上编译了它
您的程序具有未定义的行为。首先,格式说明符%x将导致printf期望类型为实参unsigned int。但是,您正在向其传递type参数int*。您要%p用于打印。最有可能的是,您正在64位计算机上工作,这意味着地址将为64位宽。一个int几乎肯定不会大到足以代表所有可能的地址。当将一种类型的参数传递给函数时,该函数会将该参数的值解释为错误的类型,这通常是未定义的行为,实际上,在这里最有可能发生的情况是,printf仅打印您的低位代码指针值解释为unsigned int。然后,让您的用户类型返回实际上仅是您实际地址的下半部分,然后将其转换回指针,然后访问该内存位置,几乎可以肯定这将不是type对象的有效地址int。那是您再次获得未定义行为的地方(幸运的是,这次将其自身显示在一个segfaul中)。
如果您想要一个可以表示指针值的整数,请使用std::uintptr_t。而且,只是不要在C ++中使用C样式强制转换。它们在那里是为了向后兼容C代码。C样式强制转换没有优势,但有许多劣势(例如,请参阅this或this或this或this问题以获取更多信息)。另外,printf不是安全类型,请勿使用printf。您的问题再次证明了这一点(例如,请参阅此处以了解更多信息)。如果您使用它std::cout,则指针将自动正确打印。一般来说,printf希望您注意确保实际传递的参数类型与格式字符串中指定的类型相匹配。如果您犯任何错误,最终将导致未定义的行为。std::cout另一方面,将做正确的事情或无法编译。最后,我只是不由自主,但请注意看到std::cin被用于输入再printf被用于输出,这真的是多么的奇怪……
| 归档时间: |
|
| 查看次数: |
214 次 |
| 最近记录: |