Pagina 1 di 1

ricavare la dimensione di un array in c usando un puntatore

Inviato: gio 3 mag 2007, 20:45
da absinthe
chiedo scusa per il titolo un pò nebuloso ma non mi bastavano i caratteri per descivere la cosa...
purtroppo sono abbastatnza arrugginito in c, vi spiego il problema: ho un array di strutture da me realizzate, per semplicità diciamo:

Codice: Seleziona tutto

//my struct
typedef struct _apoint {
int x;
int y;
} point;
questo array è statico, viene definito nel main da me, senza allocazione dinamica etc...:
devo passare l'array ad una funzione che lo manipola . tale funzione è generica e fa parte di una libreria scritta da me ma a cui linko staticamente diversi eseguibili che devo gestire. non mi ricordo come (se) fare per far capire la dimansione del vettore alla funzione. pensavo di fare un prototipo di funzione tipo:

Codice: Seleziona tutto

//prototype
void funzione_libreria(point *ptr);

e di passare l'array tramite la chiamata:

Codice: Seleziona tutto

int main () {
point data[10];
funzione_libreria(data);
//...
return 0;
}
il fatto è che non so come ricavarmi la dimensione dell'array,se implemento nella funzione qualcosa tipo:

Codice: Seleziona tutto

void funzione_libreria(point *ptr) {
//...
int dimension=(int) sizeof(ptr)/sizeof(ptr[0]);
//...
}
succede un ovvio macello... non mi ricordo come venirne a capo :-/
qualche anima pia mi ricorda come fare? o dove leggere come fare? denghiù!

M

Re: ricavare la dimensione di un array in c usando un puntat

Inviato: gio 3 mag 2007, 20:59
da corrado
absinthe ha scritto:chiedo scusa per il titolo un pò nebuloso ma non mi bastavano i caratteri per descivere la cosa...
purtroppo sono abbastatnza arrugginito in c, vi spiego il problema: ho un array di strutture da me realizzate, per semplicità diciamo:

Codice: Seleziona tutto

//my struct
typedef struct _apoint {
int x;
int y;
} point;
questo array è statico, viene definito nel main da me, senza allocazione dinamica etc...:
devo passare l'array ad una funzione che lo manipola . tale funzione è generica e fa parte di una libreria scritta da me ma a cui linko staticamente diversi eseguibili che devo gestire. non mi ricordo come (se) fare per far capire la dimansione del vettore alla funzione. pensavo di fare un prototipo di funzione tipo:

Codice: Seleziona tutto

//prototype
void funzione_libreria(point *ptr);

e di passare l'array tramite la chiamata:

Codice: Seleziona tutto

int main () {
point data[10];
funzione_libreria(data);
//...
return 0;
}
il fatto è che non so come ricavarmi la dimensione dell'array,se implemento nella funzione qualcosa tipo:

Codice: Seleziona tutto

void funzione_libreria(point *ptr) {
//...
int dimension=(int) sizeof(ptr)/sizeof(ptr[0]);
//...
}
succede un ovvio macello... non mi ricordo come venirne a capo :-/
qualche anima pia mi ricorda come fare? o dove leggere come fare? denghiù!

M
Forse dico una cosa stupida (non ho ben capito il problema), ma se definissi la dimensione dell'array come una direttiva o una costante? Tipo :

Codice: Seleziona tutto

#define ARRAYDIM  10
oppure

Codice: Seleziona tutto

const int arraydim = 10;
Se sbaglio non infierire...

Saluti
corrado

Inviato: gio 3 mag 2007, 21:20
da tgmx
aggiungi un parametro alla funzione e passagli la dimensione dell'array...

Inviato: gio 3 mag 2007, 21:21
da ildiama
Sì, la cosa che dici è strana. O forse ho capito male io. Comunque... in C non si dichiarano array senza dimensione. Cioè, per dichiararlo devi fare una cosa tipo

Codice: Seleziona tutto

point p[dimensione];
dove dimensione è un intero ed è il numero di elementi. Da lì la dimensione dell'array si può ottenere con una cosa tipo

Codice: Seleziona tutto

sizeof(point) * dimensione
Se basta così ok. Se non ho capito una mazza chiedi pure. Ciao

Inviato: gio 3 mag 2007, 21:35
da elettronicha
voto per la soluzione proposta da corrado.
l'array è statico e va allocato, quindi basta impostare una variabile globale con una direttiva o con il modificatore "const" (meglio la prima).
rileggi la documentazione dell'operatore sizeof, esso restituisce la dimensione in byte. comunque non ho capito cosa significhi:

int dimension=(int) sizeof(ptr)/sizeof(ptr[0]);

Inviato: gio 3 mag 2007, 21:40
da tgmx
La soluzione di corrado non credo vada bene perchè se la funzione appartiene ad una libreria e una libreria si presume debba essere portabile non si può basare su una variabile globale.

E' di gran lunga preferibile, secondo me, che la funzione accetti oltre al puntatore all'array anche un intero contenente le sua dimensione.

Inviato: gio 3 mag 2007, 21:43
da elettronicha
è vero! non ci avevo fatto caso che fosse una libreria.

Re: ricavare la dimensione di un array in c usando un puntat

Inviato: ven 4 mag 2007, 0:49
da phobos3576
absinthe ha scritto:... il fatto è che non so come ricavarmi la dimensione dell'array,se implemento nella funzione qualcosa tipo:

Codice: Seleziona tutto

void funzione_libreria(point *ptr) {
//...
int dimension=(int) sizeof(ptr)/sizeof(ptr[0]);
//...
}
succede un ovvio macello...
Succede un ovvio macello perché, all'interno di funzione_libreria, l'identificatore ptr rappresenta l'indirizzo di una struttura point e non una struttura point; di conseguenza, sizeof(ptr) ti restituisce la dimensione di un indirizzo di memoria!

Il metodo che tu intendevi usare consiste nello scrivere:

Codice: Seleziona tutto

int dimensione_array = sizeof(nome_array) / sizeof(nome_array[0]);
Il problema è che in C, per motivi di efficienza, quando si passa un array ad una funzione in realtà viene passato l'indirizzo del primo elemento dell'array stesso!
Allora, come ha scritto tgmx, aggiungi un parametro alla funzione e usalo per passare la dimensione dell'array. In alternativa, puoi creare l'array come vettore di puntatori a elementi di tipo point; l'ultimo elemento del vettore lo fai puntare a NULL in modo che la funzione sappia quando ha raggiunto la fine del vettore stesso.

Inviato: ven 4 mag 2007, 9:19
da lamarozzo
tgmx ha scritto:aggiungi un parametro alla funzione e passagli la dimensione dell'array...
IMHO questo e' il modo corretto di farlo in C. Negli array del C non c'e' nessuna informazione sulla lunghezza dello stesso e quindi la lunghezza va passsata direttamente alla funzione che deve manipolarlo. Altrimenti c'e' il rischio di andare a leggere/scrivere su altri indirizzi di memoria con effetti imprevedibili!

Se sei in C++ invece puoi usare il template vector della STL.

Re: ricavare la dimensione di un array in c usando un puntat

Inviato: ven 4 mag 2007, 17:19
da absinthe
phobos3576 ha scritto:
absinthe ha scritto:... il fatto è che non so come ricavarmi la dimensione dell'array,se implemento nella funzione qualcosa tipo:

Codice: Seleziona tutto

void funzione_libreria(point *ptr) {
//...
int dimension=(int) sizeof(ptr)/sizeof(ptr[0]);
//...
}
succede un ovvio macello...
Succede un ovvio macello perché, all'interno di funzione_libreria, l'identificatore ptr rappresenta l'indirizzo di una struttura point e non una struttura point; di conseguenza, sizeof(ptr) ti restituisce la dimensione di un indirizzo di memoria!
già l'"ovvio" era riferito a questo: all'inizio avevo implementato così senza riflettere, poi mi ero accorto della vaccata ma anche del fatto che non mi veniva in mente nessuna soluzione se non quella di passare la dimensione... credevo ci fosse un modo per far calcolare la "lunghezza" in automatico...
Il metodo che tu intendevi usare consiste nello scrivere:

Codice: Seleziona tutto

int dimensione_array = sizeof(nome_array) / sizeof(nome_array[0]);
Il problema è che in C, per motivi di efficienza, quando si passa un array ad una funzione in realtà viene passato l'indirizzo del primo elemento dell'array stesso!
Allora, come ha scritto tgmx, aggiungi un parametro alla funzione e usalo per passare la dimensione dell'array. In alternativa, puoi creare l'array come vettore di puntatori a elementi di tipo point; l'ultimo elemento del vettore lo fai puntare a NULL in modo che la funzione sappia quando ha raggiunto la fine del vettore stesso.
mmm... grazie! credo che userò la prima soluzione: mi pare la più rapida anche nell'ottica di dover passare la libreria a qualcun'altro!

M

Inviato: ven 4 mag 2007, 23:16
da absinthe
elettronicha ha scritto:voto per la soluzione proposta da corrado.
l'array è statico e va allocato, quindi basta impostare una variabile globale con una direttiva o con il modificatore "const" (meglio la prima).
rileggi la documentazione dell'operatore sizeof, esso restituisce la dimensione in byte. comunque non ho capito cosa significhi:

int dimension=(int) sizeof(ptr)/sizeof(ptr[0]);
beh... nel mio caso niente ;) in generale, se implementato con criterio, serve per ricavarsi la dimensione di un array, come ha scritto anche phobos3576. ad esempio io lo utilizzo negli applicativi quando mi serve di avere a portata di mano la dimensione di una stringa definita dal preprocessore. esempio stupido in un file pippo.h:

Codice: Seleziona tutto

#ifndef PIPPO_H
#define PIPPO_H

#define CODENAME "edgy"
#define CODENAMESIZE sizeof(CODENAME)/sizeof(CODENAME[0])

#endif //pippo.h
in questo modo modifichi il nome in codice nel file .h e ovunque nel resto dei sorgenti tutto si aggiorna automaticamente: stringa del nome in codice e lunghezza associata

M.