我很好奇为什么在这段代码中,*(ptr + 1)的值在程序运行时变为1而不是6。
#include <stdio.h>
int main (void)
{
int *ptr, content = 3;
ptr = &content;
*(ptr + 1) = 6;
*(ptr + 2) = 10;
*(ptr + 3) = 14;
int i = 0;
for (i = 0; i < 4; ++i)
{
printf("The address is %p and the content is %d \n", ptr+i, *(ptr+i));
}
return 0;
}
当run int 6被修改为值为1时。
*(ptr + 1) = 6;
以下是该计划的输出:
The address is 0x7fff7b400a88 and the content is 3
The address is 0x7fff7b400a8c and the content is 1
The address is 0x7fff7b400a90 and the content is 10
The address is 0x7fff7b400a94 and the content is 14
我在valgrind中运行它并没有出现任何错误或任何错误,也尝试使用谷歌搜索它也许我正在寻找错误的东西,但没有找到结果的运气。
答案 0 :(得分:4)
您修改未分配给您的内存,因此这是未定义的行为。
可能发生的是变量i
被分配到该位置,因为它是下次使用堆栈空间在功能中。此时 i
为1 。所以输出为1 。
更改
int content = 3;
ptr = &content;
到
int content[10] = {3};
ptr = &content[0]; //or ptr = content; but this may be harder to grasp if you are new to C
(感谢@KeithThompson修复指针赋值)
如果您只是尝试指针算术。这将起作用,因为现在您拥有10 int
s
答案 1 :(得分:2)
程序通过恶意指针修改内存。最有可能的是,指针会指向恰好存储i
的位置,因此它会在该点输出i
的值。
修复错误,神秘感将会消失。了解错误的程序比理解正确的程序要复杂得多。
答案 2 :(得分:1)
看起来你正在为i
留出的内存中写入变量。不管怎样,不知道为什么它对你很重要,因为你不应该写下你没有明确分配的数据。
答案 3 :(得分:0)
您正在将ptr移动到指向您尚未分配的内存,并获取编译器放置的内容。
答案 4 :(得分:0)
您的代码正在写入未作为数组的一部分分配的地址,因此调用未定义的行为。任何事情都可能发生,而且是正确的。
最有可能发生的事情是变量i
存储在0x7FFF7B400A8C并正在修改打印的内容。
答案 5 :(得分:0)
*(ptr + 1) = 6;
*(ptr + 2) = 10;
*(ptr + 3) = 14;
在上述陈述中发生了堆栈损坏,这是一种未定义的行为。因为你的程序只能访问*(ptr + 0),所以幸运的是没有发生崩溃。
为什么*(ptr + 1)
正在打印1
,它指向下一个在堆栈中声明的变量。这意味着它指向i
。尝试在*(ptr + 1)
循环之前打印for
,它将打印0.并尝试打印i
的地址,它将与(ptr + 1)
相同。
在int i = 0;
之后和for
循环之前声明另外两个变量,如下所示,然后运行时,在打印10
时也不会获得14
和*(ptr + 2)
*(ptr * 3)
int i = 0;
int x = 2;
int y = 2;
printf("%d", *(ptr + 1)); //this will print 0
for (i = 0; i < 4; ++i)
{
....
}
修正您的问题是,将content
作为大小为4的数组,如下所示。
...
int *ptr = NULL;
int content[] = {3, 0, 0, 0};
ptr = content;
...