【问题标题】:Pointer incrementation causing segmentation fault指针递增导致分段错误
【发布时间】:2014-05-08 01:54:08
【问题描述】:

此代码在运行时会导致分段错误。这是由于奇怪的指针增量,但我不明白为什么这是一个问题,因为它似乎有道理。

我认为它应该:增加指针,然后取消引用未增加的指针,然后将值 10 增加到 11。所以 out = 11,数组中的第一个值现在是 11。所以这个循环应该打印出 11, 21、31、1,然后继续无限打印出数组外的值。这显然是不好的做法,但我们只是想看看为什么这种双指针递增无效。

我的代码:

int main() {
     int myarray[4] = {10,20,30,0};
     int *p = myarray;
     int out = 0;
     while (out = ++(*p++)) {
         printf("%d ", out);
     }
 }          

【问题讨论】:

  • 为什么你会假设 ++(*p++) 先增加数字然后增加指针?
  • 我从来没有说过它确实如此......
  • 好吧,您假设结果应该是 11、21、31、1 而不是 10、21、31、1。也可以改写问题。 “为什么你会假设数组内容的增量在非增量指针上增加?”
  • 因为指针是递增的。首先,*p++ 递增指针并返回未递增的值。所以它返回 10。然后 ++(..) 将其增加到 11。
  • 增量有效;代码同for (int i = 0; myarray[i] != -1; ++i) { printf("%d ", ++myarray[i]); }

标签: c pointers segmentation-fault pointer-arithmetic


【解决方案1】:

while 循环永远不会终止:

第一次迭代:

*p = 10, out = 11

下一次迭代:

*p = 20, out = 21

下一次迭代:

*p = 30, out = 31

下一次迭代:

*p = 0, out = 1

下一次迭代:

您正在访问未经授权的内存,这会导致未定义的行为。

更新

在访问数组中的最后一项后,堆栈帧中包含代码的部分会被增量运算符踩踏。因此,不能期望代码以逻辑方式运行。

【讨论】:

  • 那么为什么我们在第一个输出超出数组边界之前看不到它呢?它只是说分段错误,没有任何输出。
  • @user2666425,这就是未定义行为的本质。你不能指望任何事情都是合乎逻辑的。
  • @R Sahu,在其他测试用例中,我们可以看到它输出有效的数组值,然后是疯狂的随机内存位置。我不明白为什么它现在似乎在程序开始时检测到问题。
  • @user2666425:答案可能是缓冲printf() 的输出。通常,在写入终端(屏幕)时,stdout 在换行符上刷新,否则 C 标准库将等待缓冲区(通常为 8KB 左右)填满,然后再写出任何内容。将空格更改为\n,您应该会看到崩溃前的初始输出。
  • @j_random_hacker 那是正确的,伙计。谢谢你们俩
【解决方案2】:

这里:

while (out = ++(*p++))

预增量(第一个“++”)返回增量值。因此,当您到达数组的末尾时,它会返回 1,其计算结果为 true,并且循环继续进行。

【讨论】:

    【解决方案3】:

    p 超出myarray 的范围时,deference 会导致未定义的行为。

    【讨论】:

      猜你喜欢
      • 2014-10-15
      • 2021-05-25
      • 1970-01-01
      • 2021-03-02
      • 2016-05-03
      • 1970-01-01
      • 2013-07-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多