C指针工作(但不是我预期的)

时间:2014-04-23 08:21:06

标签: c pointers

我正在阅读斯坦福大学的Essential C文档(PDF)和第20页,其中列出了以下代码:

int* p
*p = 13; // NO NO NO p does not point to an int yet
         // this just overwrites a random area in memory

这对我没有意义。

据我了解,我们为第一行的整数指定空间,所以为什么我们不能在第二行直接指向一个整数的值(例如13)。

请详细解释(图表非常有用)正在发生的事情以及失败的原因。

3 个答案:

答案 0 :(得分:12)

int *p;
*p = 13;

这意味着:

  • 创建一个可以将指向任何地方的整体指针p
  • 尝试在该位置存储13

图形:

+---+                      +---+
| p | --> points to ?????? |   |
+---+                      +---+
                             ^
                             |
  13 goes into here ---------+

由于p未初始化,因此尝试使用它存储值时未定义行为。

未初始化的行为相当令人讨厌(我的一个更低调的断言)。

可以完美地运作。它似乎工作但腐败的东西。它可能会使您的代码崩溃。它可能会影响您的代码,从而在三天后出现问题。它可能会使你的CPU陷入赤裸裸的奇点,带走你和你的家人。

它可能涉及生产鼻子恶魔和/或空气传播的猪: - )

底线是你不应该这样做。


从您的问题来看,您似乎认为*p = 13;使p指向值13。情况并非如此,特别是因为文字13实际上不可寻址。执行此操作的代码类似于:

int xyzzy = 13;     // xyzzy IS addressible,
int *p = &xyzzy;    // so make p point at it.

再次,以图形方式:

                          xyzzy
+---+                     +----+
| p | --> points to xyzzy | 13 |
+---+                     +----+

这会将p设置为指向包含13的整数xyzzy

答案 1 :(得分:4)

首先解释一下:局部变量未初始化。如果声明变量,则其值将是不确定的。使用未初始化的局部变量会导致undefined behavior

然后问你的问题:你说

  

那么为什么我们不能马上指向第二行的整数值(例如13)。

但这不是第二行实际上在做的事情。假设p已经 指向某个有效的内存区域,然后取消引用指针以将值13写入该内存区域。如果指针p是局部变量并且尚未初始化为实际指向任何位置,那么它实际上将包含一个看似随机的值,该值将是它指向的地址。

答案 2 :(得分:1)

int* p;

上述行的含义是p is a pointer to integer。但是因为我们还没有定义p本身具有什么地址,即我们还没有真正定义p指向的确切位置。我们所知道的是它所拥有的地址(或将来会保留的地址)实际上是整数的地址。所以现在,p指向任何东西,我们无法确定它。

现在你做的时候

*p = 3;

由于此时p中的地址并非由我们指定,因此p很可能指向无法写入的地址。所以行为几乎没有定义。

你应该做的是

int myInt;
int* p;
p = &myInt;
*p = 3;

上面代码的作用是,它使p保存变量myInt的地址。然后,写入该地址。

你还能做什么呢

int* p;
p = (int *)malloc(sizeof(int));

我不确定你是否熟悉malloc(别担心,你会迟到)。但它的作用是,它为p提供了一块内存(等于整数的大小),现在p指向那个特定的内存块。现在,我们不需要知道该内存块中包含的确切内容,但我们需要知道的是,已经分配给我们的内存可以在没有任何未定义的行为的情况下写入。

干杯