为什么指针值被修改为值1?

时间:2013-01-03 02:46:47

标签: c pointers

我很好奇为什么在这段代码中,*(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中运行它并没有出现任何错误或任何错误,也尝试使用谷歌搜索它也许我正在寻找错误的东西,但没有找到结果的运气。

6 个答案:

答案 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;
...