在“ for”循环初始化器中取消引用指针会产生分段错误

Mar*_*k R 45 c pointers for-loop declaration

我在for循环中使用指针时遇到问题。在for循环初始化程序中,我取消引用int指针并将其值设置为“ 0”。当我在循环中使用该取消引用的指针时,出现了段错误,并且我不明白为什么。我正在使用Code :: Blocks和C GNU GCC编译器。

  1. 看着观察窗口,我可以看到在for循环过程中变量有一个随机数。

  2. 似乎已取消引用的指针在for循环期间丢失了作用域。

代码:

#include <stdio.h>

int main(void)
{
    int val = 0;
    int *p = NULL;
    int answer = 0;

    p = &val;

    *p = 1; // This dereferences and sets to one successfully

    for (int i=3, (*p)=0 ; i>=0; i--) // Here *p is a random number
    {
        printf("do stuff");
        (*p) += 1; // Here it causes a segmentation fault
    }
    answer = *p;
}
Run Code Online (Sandbox Code Playgroud)

我认为以我的方式使用指针不会有问题。

dbu*_*ush 61

在这里仔细看看:

for (int i=3, (*p)=0 ; i>=0; i--)
Run Code Online (Sandbox Code Playgroud)

在您的第一部分中,for您将定义一个名为的指针变量p,该变量将p先前定义的阴影遮盖并将其初始化为NULL。然后,在导致段错误的循环中取消引用NULL指针。

不能同时具有变量定义和对现有变量的赋值,因此请将的赋值移动*p到循环之前:

*p = 0;
for (int i=3; i>=0; i--)
Run Code Online (Sandbox Code Playgroud)

或者,您可以i在循环之外定义:

int i;
for (i=3, (*p)=0 ; i>=0; i--)
Run Code Online (Sandbox Code Playgroud)

可以通过滥用逗号运算符将它们压缩在一起:

for (int i=(*p=0,3) ; i>=0; i--)
Run Code Online (Sandbox Code Playgroud)

这里的赋值是p作为初始化程序的一部分发生的,i因此它不会声明新变量。但是我不建议这样做,因为它会使您的代码更难以阅读和理解。

  • 由于他们使用了GCC,因此可能值得注意的是`gcc -Wshadow`会对此发出警告。 (13认同)

Nik*_* C. 28

您正在声明一个全新的变量p

for (int i=3, (*p)=0 ; i>=0; i--)
Run Code Online (Sandbox Code Playgroud)

这与:

for (int i=3, *p=0 ; i>=0; i--)
Run Code Online (Sandbox Code Playgroud)

因此,您要创建一个int iand和int *p,它指向地址0。这与p先前定义的地址不同。它只是阴影。因此,当取消引用它时,就会出现段错误。