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

aaccordino

Nuovo Utente
3
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.
 

fabio93

Utente Attivo
609
173
CPU
AMD Ryzen 5 2400G
Dissipatore
Arctic Alpine64 Plus
Scheda Madre
Gigabyte GA-AX370-Gaming 3
HDD
Crucial MX500 250 GB, Crucial BX500 240 GB
RAM
G.Skill F4-3200C14D-16GFX FlareX 16 GB
Monitor
HP 2010i
PSU
Corsair TX550M
Case
Sharkoon M25-W
Periferiche
Magicforce 68, Logitech G203
OS
Windows 10 Pro, Fedora 31
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:

aaccordino

Nuovo Utente
3
2
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?
 

fabio93

Utente Attivo
609
173
CPU
AMD Ryzen 5 2400G
Dissipatore
Arctic Alpine64 Plus
Scheda Madre
Gigabyte GA-AX370-Gaming 3
HDD
Crucial MX500 250 GB, Crucial BX500 240 GB
RAM
G.Skill F4-3200C14D-16GFX FlareX 16 GB
Monitor
HP 2010i
PSU
Corsair TX550M
Case
Sharkoon M25-W
Periferiche
Magicforce 68, Logitech G203
OS
Windows 10 Pro, Fedora 31
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.
 
  • Mi piace
Reazioni: BAT

Andretti60

Utente Èlite
6,440
5,091
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.
 
  • Mi piace
Reazioni: fabio93

fabio93

Utente Attivo
609
173
CPU
AMD Ryzen 5 2400G
Dissipatore
Arctic Alpine64 Plus
Scheda Madre
Gigabyte GA-AX370-Gaming 3
HDD
Crucial MX500 250 GB, Crucial BX500 240 GB
RAM
G.Skill F4-3200C14D-16GFX FlareX 16 GB
Monitor
HP 2010i
PSU
Corsair TX550M
Case
Sharkoon M25-W
Periferiche
Magicforce 68, Logitech G203
OS
Windows 10 Pro, Fedora 31
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:
  • Mi piace
Reazioni: Andretti60

Andretti60

Utente Èlite
6,440
5,091
Auguri per il tuo nuovo lavoro dunque!
Se conosci l’inglese, non dimenticare il sito stackoverflow (nome azzeccatissimo) è la manna del professionista.
 
  • Mi piace
Reazioni: fabio93

Ci sono discussioni simili a riguardo, dai un'occhiata!

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!

Discussioni Simili