c for-loop pointers declaration

Anular la referencia de un puntero en un inicializador de bucle ''for'' crea un error de segmentación



for-loop pointers (3)

Tengo un problema al usar punteros en un bucle for . En mi inicializador de bucle for , hago referencia a un puntero int y le doy un valor de ''0''. Cuando uso ese puntero desreferenciado en el bucle, aparece un error de segmentación y no entiendo por qué. Estoy usando Code::Blocks y el compilador C GNU GCC.

  1. Mirando la ventana de observación, puedo ver que durante el ciclo for la variable tiene un número aleatorio.

  2. Parece que el puntero desreferenciado pierde alcance durante el ciclo for .

El código:

#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; }

Pensé que no habría problemas al usar un puntero como soy.


Consejo: Use -Wshadow para obtener una advertencia cuando una variable -Wshadow a otra.

[] $ gcc main.c -Wshadow main.c: In function ‘main’: main.c:13:21: warning: declaration of ‘p’ shadows a previous local [-Wshadow] 13 | for (int i=3, (*p)=0 ; i>=0; i--) // Here *p is a random number | ^ main.c:6:10: note: shadowed declaration is here 6 | int *p = NULL; | ^

https://coliru.stacked-crooked.com/a/5de37f53cf0b094d


Está declarando una variable completamente nueva llamada p :

for (int i=3, (*p)=0 ; i>=0; i--)

Esto es lo mismo que:

for (int i=3, *p=0 ; i>=0; i--)

Entonces, está creando un int i y un int *p , que apunta a la dirección 0. Esta no es la misma p que la definida anteriormente. Simplemente lo sombrea. Entonces, cuando lo desreferencia, obtiene el segfault.


Mira de cerca aquí:

for (int i=3, (*p)=0 ; i>=0; i--)

En la primera parte de for , está definiendo una nueva variable de puntero llamada p que sombrea la p definida anteriormente e inicializándola en NULL. Luego, desreferenciar el puntero NULL en el bucle que causa la segfault.

No puede tener una definición de variable y una asignación a una variable existente juntas de esa manera, así que mueva la asignación de *p antes del ciclo:

*p = 0; for (int i=3; i>=0; i--)

O puede definir i fuera del bucle:

int i; for (i=3, (*p)=0 ; i>=0; i--)

Puede juntarlos abusando del operador de coma:

for (int i=(*p=0,3) ; i>=0; i--)

Aquí la asignación a p ocurre como parte del inicializador para i por lo que no declara una nueva variable. Pero no recomendaría esto, ya que haría que su código sea más difícil de leer y comprender.