Soy un principiante de C y encontré este código al intentar implementar una lista vinculada.
struct Node *ptr = malloc(sizeof(*ptr));La estructura del nodo se ve así:
struct Node { int data; struct Node *next; }; Estoy tratando de entender la primera línea. Parece que malloc(sizeof(*ptr)) ya conoce el contenido de ptr . ¿Qué sucede exactamente en el lado izquierdo y sucede antes de que se llame a malloc?
Solo use paréntesis con sizeof si hay un tipo del que le gustaría saber el tamaño. Si tiene una expresión , como *ptr , basta con escribir:
struct Node *ptr = malloc(sizeof *ptr); // <- no parenthesis La expresión *ptr elimina la referencia del puntero para que se convierta en un struct Node y para eso sizeof devuelve el tamaño.
sizeofexpression: devuelve el tamaño, en bytes, de la representación de objeto del tipo de expresión. No se aplican conversiones implícitas a la expresión.
Es del mismo tamaño que obtienes si lo haces:
struct Node *ptr = malloc(sizeof(struct Node)); // <- parenthesis neededpero la primera alternativa es a menudo preferible por claridad.
Parece que
malloc(sizeof(*ptr))ya conoce el contenido deptr.
En realidad, no lo hace. El operador sizeof en realidad no evalúa su operando (a menos que sea una matriz de longitud variable), solo mira su tipo. Esto significa que ptr en realidad no está desreferenciado y, por lo tanto, es una operación segura.
Debe asignar una memoria para un objeto del tipo struct Node declarado como
struct Node { int data; struct Node *next; };Entonces, en la llamada de malloc, debe especificar el tamaño de la memoria que se asignará para un objeto de este tipo. La función malloc devuelve un puntero a la memoria asignada.
para que puedas escribir
struct Node *ptr = malloc( sizeof( struct Node ) ); Por otro lado, la expresión *ptr tiene el tipo struct Node. Es decir, el puntero declarado ptr tiene el tipo de puntero struct Node * y la desreferenciación de un puntero como *ptr produce una expresión del tipo struct Node .
Entonces puede reescribir el registro anterior también como
struct Node *ptr = malloc(sizeof(*ptr)); porque en este caso sizeof( struct Node ) es equivalente a sizeof( *ptr ) .
Es decir, el compilador necesita saber el tipo del operando del operador sizeof eso para determinar el tamaño de un objeto de ese tipo.