1

我很好奇为什么在这段代码中 *(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;
 }

运行时 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 中运行它并且没有出现任何错误或任何东西,还尝试使用谷歌搜索它,也许我正在寻找错误的东西但没有运气找到结果。

4

6 回答 6

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 修复了指针分配)

如果您只是尝试指针算术。int这将起作用,因为现在您拥有 10 s数组中的整个堆栈空间

于 2013-01-03T02:49:09.367 回答
2

该程序通过流氓指针修改内存。最有可能的是,指针最终指向i恰好存储的位置,因此它输出该i点的值。

修复错误,谜团就会消失。理解有缺陷的程序比理解正确的程序要复杂得多。

于 2013-01-03T02:49:21.537 回答
1

看起来您正在将变量写入为i. 不知道为什么它对你很重要,因为你不应该覆盖你没有明确分配的数据。

于 2013-01-03T02:50:36.273 回答
0

您正在移动 ptr 以指向尚未分配的内存,并获取编译器放在那里的任何内容。

于 2013-01-03T02:50:45.890 回答
0

您的代码正在写入未作为数组的一部分分配的地址,因此正在调用未定义的行为。任何事情都可能发生,而且是正确的。

最有可能发生的事情是变量i存储在 0x7FFF7B400A8C 并且正在修改打印的内容。

于 2013-01-03T02:50:46.650 回答
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声明两个变量,如下所示,然后运行你不会得到1014同时打印*(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;
...
于 2013-01-03T09:08:12.463 回答