DOMANDA [C] Array 2D copiato su punutatore, valore di sizeof?

Pubblicità

aaccordino

Nuovo Utente
Messaggi
3
Reazioni
2
Punteggio
2
Ciao a Tutti, spero di trovare qualche buon cuore con competenze di C a sufficienza da spiegarmi questa cosa.
Per spiegare il mio dubbio ho creato questo codice:

Codice:
#include <stdio.h>

char* global[] = {  "123456789",  "abcdefghi",  "987654321" };

int main()
{
    char ** local;
    local = global;
   
    printf("local pointer: %d\n", local);
    printf("sizeof local: %d\n", sizeof(local));
   
    printf("global pointer: %d\n", global);
    printf("sizeof global: %d\n", sizeof(global));
   
    return 0;
}

Che da in output la seguente:

local pointer: 6295616
sizeof local: 8
global pointer: 6295616
sizeof global: 24

Come vedete, la copia puntatore avviene correttamente, infatti l'indirizzo è lo stesso. Ma il sizeof è sbagliato in entrambi (dovrebbero essere 9 caratteri per stringa più il terminatore, quindi 30 se non ho capito male). Ma ciò che capisco ancora di meno è il perché sono diversi tra loro (global e local).

Grazie in anticipo a chiunque vorrà spiegarmi questa cosa.
 
L'operatore sizeof restituisce la dimensione in byte del suo argomento. Sul tuo pc i puntatori a char e i puntatori a puntatore a char occupano 8 byte (come solitamente accade su macchine a 64 bit). La variabile local è un puntatore a puntatore a char, perciò sizeof(local) = 8.
Nel caso di global vale 24, ovvero 8x3, perché global è un array e, in questo caso, sizeof restituisce la dimensione in byte dell'intero array il quale, essendo un array di tre puntatori a char, occupa 3x8=24 byte.

Se vuoi ottenere la lunghezza di una stringa devi usare la funzione strlen, per cui ad esempio strlen(local[0]) = 9 (idem per global).
 
Ultima modifica:
Ciao Fabio!

Ti ringrazio per la risposta!
Non capisco però perché dopo l'assegnazione, sizeof restituisce un valore diverso nei due casi, una volta copiato non dovrebbero puntare entrambi all'array di 3 puntatori?
 
Non c'entra a cosa puntano. L'operatore sizeof restituisce la dimensione dell'argomento che gli viene passato, non della variabile a cui questo punta eventualmente. Siccome local è un puntatore a puntatore a char, pesa 8 byte (in genere i puntatori hanno tutti lo stesso peso a prescindere dal tipo di dato, su macchine a 64 bit tipicamente è di 8 byte) e sizeof(local) = 8.
Con gli array sizeof restituisce la dimensione dell'intero array, ecco perché sizeof(global) = 24;
Ricapitolando, local è un puntatore e pesa 8 byte, mentre global è un array, e il suo peso equivale al peso di ciascun elemento per il numero di elementi.
 
Questo è uno degli esercizi più ostici per chi inizia il C, era (e forse lo è ancora) una delle domande preferite nei colloqui di lavoro.
I due puntatori sono molto diversi. Uno alloca spazio nello heap, e lo alloca staticamente, l’altro invece non alloca nulla, è un puntatore che risiede nello stack. Una volta che capisci come la memoria viene allocata, il risultato dei printf è immediato. La spiegazione di @fabio93 non fa una piega.
 
Grazie @Andretti60!
Aggiungo che se global fosse stato dichiarato non come array statico ma come puntatore a puntatore a char, facendo uso di malloc per allocare dinamicamente la memoria (per l'intero array e per ogni stringa elemento), si avrebbe sizeof(global)=8 perché, come prima era per local, sizeof darebbe la dimensione del solo puntatore, non dell'array puntato.
 
Ultima modifica:
Auguri per il tuo nuovo lavoro dunque!
Se conosci l’inglese, non dimenticare il sito stackoverflow (nome azzeccatissimo) è la manna del professionista.
 
Pubblicità
Pubblicità
Indietro
Top