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.
-
Mirando la ventana de observación, puedo ver que durante el ciclo
for
la variable tiene un número aleatorio. -
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;
| ^
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.