Newsgroup: it.comp.lang.c++
Titolo: Uso di calloc in VC++ 6

Il mio probema è questo:
#include "stdlib.h"
#include "stddefh."
void miaFunzione(int N)
{
   int **Array;
   ....
   Array = (int **)calloc(N, sizeof(int));
   ....
}
Il compilatore non dà errori, ma in esecuzione, in corrispondenza
della chiamata a calloc, si apre una dialog box che mi chiede di
individuare DBGHEAP.C.
perchè???
Nabira

C'è un errore :
forse volevi fare questo :
    //<CODE>
    void miaFunzione(int N)
    {
       int **Array;
       Array = (int **) calloc(10, sizeof(int*));
       for(int i = 0; i < 10; ++i)
       {
          Array[i] = (int*) calloc(10, sizeof(int));
       }
    }
    //</CODE>
alla calloc gli devi dire quanti elementi allocare e la "dimensione
di quello che Array punterà", in questo caso array punterà ad un array
di 10 puntatori a interi. Ti consiglio di andare a fondo della questione
puntatori altrimenti non ne esci.
Chiaro ? spero di si, comunque di seguito un
esempiuccio di utilizzo :
    int **myArray;
    myArray = (int **) calloc(10, sizeof(int*));
    for(int i = 0; i < 10; ++i)
    {
       myArray[i] = (int*) calloc(10, sizeof(int));
    }
    for(int i = 0; i < 10; ++i)
    {
       for(int j = 0; j < 10; ++j)
          myArray[i][j] = 1;
    }
    for(int i = 0; i < 10; ++i)
    {
       std::cout << std::endl;
       for(int j = 0; j < 10; ++j)
          std::cout << myArray[i][j];
    }
Il consiglio che ti do è di utilizzare i vector della STL.
Ciao.


Grazie, ma il problema non sussisteva, infatti la richiesta del file
DBGHEAP.H avviene solo in debug, se si mette un breakpoint
sull'istruzione 'calloc'.
ciao
Nabira

          std::cout << myArray[i][j];
idem a quanto sopra : mi aspetterei qualche "cristo" sulle 
dimensioni incognite (quelle precedenti la più a destra).
O sono rimasto indietro, o i compilatori odierni capiscono un 
sacco di cose dal contesto, il che può anche essere. Il vecchio 
Borland mi dava errore, ma non ho provato a ricompilare ora
ciao
Soviet_Mario


 l'indirizzo corretto ?
Non è esattamente una matrice, è un array di puntatori, ognuno dei quali 
punta ad un array. Ogni riga potrebbe avere una dimensione diversa.
E.

 usata come una matrice statica ...
Viene usata applicando semplicemente l'operatore "[]", che č possibile sia
con gli array che con i puntatori. 
Max

 necessarie a produrre l'indirizzo di una cella qualsiasi. 
Se hai
float **array;
se scrivi array[2] ottieni un tipo float *. Dunque puoi scrivere 
array[2][3] per ottenere il terzo elemento della seconda riga. Non 
occorre che il compilatore conosca le dimensioni.
E.

 ha scritto nel messaggio 
news:1176715411....@o5g2000hsb.googlegroups.com...


ti consiglio un ripasso sui puntatori e gli array ...
:-))
Ciao.

 pretendo di scrivere
:-( chiedo scusa, ho formattato male il testo e mi son scappati 
dei taglia incolla errati .... per forza che poi non si capisce 
mai una mazza di quello che scrivo. Non sembro manco italiano :-(
volevo dire che non posso pretendere di scrivere quanto segue in 
una routine dichiarata come segue
Il resto è circa OK (spero si capisca meglio ... lo lascio cmq)
ciao


seconda riga, non deve sapere dove FINISCE la riga stessa ? 
Se hai: 
T **array 
(con qualsivoglia T), non esiste una "riga", esistono solo n puntatori
in sequenza, ad intervalli fissi sizeof(T*), ognuno dei quali punta a
una zona di memoria in cui sono presenti m valori ad intervalli fissi
sizeof(T).
Si applica l'aritmetica dei puntatori (mediante il primo []) per
avanzare da un puntatore all'altro e quindi si accede all'elemento
puntato (mediante il secondo []).
array[2][3] significa: accedi all'indirizzo contenuto in array,
sommando ad esso 2*sizeof(T*), quindi, essendo il valore puntato un
puntatore, somma al suo valore 3*sizeof(T) e accedi all'elemento di
tipo T.
Se hai dichiarato (T a piacere):
T *array;
scrivendo array[2] è come se scrivessi *(array+2), quindi come se
accedessi alla locazione ottenuto prendendo l'indirizzo di array e
sommando ad esso 2*sizeof(T).
Se T è un tipo puntatore: X* hai:
X **array;
quindi array[2] equivale ad accedere alla locazione ottenuta prendendo
l'indirizzo di array e sommando ad esso 2*sizeof(X*).
Siccome ciò che ottieni è a tua volta un puntatore, puoi ancora usare
l'operatore [] per accedere all'elemento specifico di tipo T.

int initialize (int **** Mat)
Non puoi passare Matr a questa funzione.
<snip su tutto il resto che non ho letto :-)>

 l'operatore [] per accedere all'elemento specifico di tipo T.
si, il ragionamento fila liscio. Boh, ancora non capisco bene 
cosa c'è di non pertinente nel problema che ho posto. Sono 
sicuro che non è un ricordo clandestino di altri linguaggi 
(perché so solo i basic e sapevo un po' di fortran, e nessuno ha 
di queste problematiche). Deve essere un ricordo del C, ma mi 
pare che quel che hai scritto per il C++ possa valere pari pari 
per C, quindi ancora sto in alto mare.
ciao
Soviet

sacco di cose dal contesto, il che può anche essere.
Direi la prima :-)

quindi ancora sto in alto mare.
Non sei in alto mare, sei appena approdato e gli indigeni ti hanno
dato una sberla :-)

 <snip su tutto il resto che non ho letto :-)>
vabbuò, cmq qui c'è un riassunto parzialmente rettificato in 
alcuni svarioni.
ciao
Soviet

 capire da quale contesto ho tratto le cose che ho scritto.
Guarda, Soviet (Mario?), secondo me tu stavi semplicemente pensando al
layout di una matrice dichiarata come array di array e al fatto che quando
si vuole passarla ad una funzione la dimensione delle righe deve apparire
nella dichiarazione dell'argomento. Un array di array puň decadere in un
puntatore ad array, ma la "decadenza" si ferma qui, perché conoscere la
dimensione delle righe č essenziale per saltare da una riga all'altra
tramite consueta aritmetica dei puntatori.
Ecco, probabilmente pensavi a questo, e non ti sei accorto che la struttura
dati di cui si stava parlando non era un array di array, ma una array di
puntatori, che -come ti ha spiegato Andrea- č qualcosa di radicalmente
diverso.
Max

 unlikely to be what the programmer intended.
Sta dicendo che la seconda funzione non funziona se ci passi un array 
dichiarato come
int array[3][4];
ma in effetti funzionerebbe nel caso tu avessi un array del tipo:
int *array[3];
int riga1[4];
int riga2[4];
int riga3[4];
array[0]=riga1;
array[1]=riga2;
array[2]=riga3;
print(array,3,4);
E.

 i puntatori non mi creano grossi problemi,
Si vede che sei fortunato :-) In generale, è sempre bene capire il
perché delle cose ;-)

 perché delle cose ;-)
ehh, o sacce. Mi aiuto molto (nel senso che ci metto spesso meno 
tempo) a scrivere cose sintatticamente inesatte e interpretare 
poi gli oracoli del compilatore e limare che non a riuscire a 
scrivere da subito cose perfette magari rivedendo il manuale. 
Non è una abitudine salutare, ne sono conscio ! Ma scrivo 
assiduamente solo in periodi saltuari purtroppo, per cui non 
mantengo mai a lungo un livello di padronanza stabile. Come una 
lingua che magari l'hai studiata varie volte e se ti concentri 
capisci cosa dice, ma non la parli e quindi non hai fluency.
E' dal 2001 che in sostanza faccio 2-3 lavori e non riesco più a 
programmare in maniera assidua, anche se mi piacerebbe.
ciao
Soviet_Mario
Ah, P.S. .... siamo in pace, adesso, vero ?

 Max

 Ah, P.S. .... siamo in pace, adesso, vero ?
Eh? in "pace"?
Mario, tanto per chiarire: io non considero le persone che rimarcano i
miei errori o quelle a cui rimarco errori come gente con cui sono "in
guerra". I ng sono fatti per discutere ed io discuto: se sbaglio,
accetto le correzioni; se qualcuno sbaglia, lo correggo (o ci provo).
Questo non significa compiere un atto di guerra.

 Questo non significa compiere un atto di guerra.
beh, a parte che l'avere usato il termine "pace" non voleva 
essere un atto di ostilità, anche guerra è una metafora.
riciao
Soviet_Mario

 ragione>, OK, perfetto.
Visto che dici che non ci intendiamo e probabilmente non ci
intenderemo, ti ricordo che quando ti è stato detto questo, non hai
risposto con "ok, perfetto", ma ti sei limitato a dire: "io sono un
dilettante e mi sta bene così". L'orgoglio va bene, ma fino a un certo
punto ;-)
Quando si affronta una discussione, in un gruppo come questo, è facile
che si finisca a parlare di regole di design e di corretta
programmazione.
Se uno ti dice di non usare "int", ma usare "size_t", per esprimere
una _dimensione_, si tratta di una regola di buona programmazione.
Poi, sul discorso "spazzatura": c'è spazzatura e spazzatura :-)... a
volte la spazzatura è talmente spazzatura, che non val neanche la pena
stare lì a discutere del perché è spazzatura ;-)

 anzi il tema degli oggetti "sparsi" mi č anche abbastanza "caro" (nel 
