Newsgroup: it.comp.programmare
Titolo: [c] Calloc e puntatori di puntatori

salve.
io ho un puntatore di puntatori di interi
  int **p;
mi fate un esempio con calloc (malloc) per aumentare prima le righe,
poi le colonne?
grazie!
(e scusate la domanda stupida, ma sono proprio un principiante)

ad esempio, perchè questo fa in core dump?
#include <stdio.h>
#include <stdlib.h>
int main ()
{
	char i, **p;
	*p=calloc(2, sizeof(char));
	p[0]="ciao";
	p[1]=calloc(2, sizeof(char));
	p[1][0]='d';
	p[1][1]='e';
	for(i=0; p[1][i]; i++) printf("%c", p[1][i]);
	printf("\n");
return 0;
}

 
Quale sarebbe la condizione di termine di questo ciclo di for?
Scritto cosi' il ciclo termina quando p[1][i] vale zero, ma quando 
dovrebbe valere zero visto che nel codice precedente non c'e' da nessuna 
parte qualcosa che metta uno zero.
La calloc mi pare di ricordare che allochi e azzeri la memoria allocata, 
ma tu hai allocato solo 2 caratteri e li hai inizializziati con 'd' 'e'.
Il resto della memoria ha un valore indefinito.
Tuttavia l'indice che stai usando e' un char, quindi a piu' di 128 non va...
a meno che col successivo incremento diventi -127 e il tuo puntatore 
punti ad un indirizzo che non e' piu' memoria, da qui il core.
E' una ipotesi, naturalmente.
Comunque, gia' che ci siamo, dopo avere allocato della memoria, e' buona 
cosa disallocarla con una bella free() prima dell'uscita del programma.

cosa disallocarla con una bella free() prima dell'uscita del programma.
Giusto, anche se deallocare la memoria non è tanto importante prima
dell'uscita del programma (ogni sistema operativo serio la rilascia,
distruggendo il processo), ma come buona regola durante la vita stessa
del programma.

	p[1]=calloc(2, sizeof(char));
p[1] non è inizializzato.
Dovresti spiegare, nello specifico, che cosa vuoi fare.

#include <stdio.h>
#include <stdlib.h>
int main ()
{
	char **p;
	int i;
	*p=calloc(2, sizeof(char));
	p[0]="ciao";
	p[1]=calloc(3, sizeof(char));
	p[1][0]='d';
	p[1][1]='e';
	p[1][2]='1';
        for(i=0; p[1][i]=='1'; i++) printf("%c", p[1][i]);
        printf("\n");
return 0;
}
Mettendo il free succede il finimondo. Mi stampa:
lucrezia@ubuntu:~/lab$ ./a.out
d
*** glibc detected *** ./a.out: double free or corruption (out):
0xbfbb9438 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6[0xb7ed78bd]
/lib/tls/i686/cmov/libc.so.6(__libc_free+0x84)[0xb7ed7a44]
./a.out[0x8048492]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xdc)[0xb7e868cc]
./a.out[0x8048341]
======= Memory map: ========
08048000-08049000 r-xp 00000000 03:01 1309542    /home/lucrezia/lab/
a.out
08049000-0804a000 rw-p 00000000 03:01 1309542    /home/lucrezia/lab/
a.out
0804a000-0806b000 rw-p 0804a000 00:00 0          [heap]
b7d00000-b7d21000 rw-p b7d00000 00:00 0
b7d21000-b7e00000 ---p b7d21000 00:00 0
b7e5c000-b7e66000 r-xp 00000000 03:01 832336     /lib/libgcc_s.so.1
b7e66000-b7e67000 rw-p 00009000 03:01 832336     /lib/libgcc_s.so.1
b7e70000-b7e71000 rw-p b7e70000 00:00 0
b7e71000-b7f9e000 r-xp 00000000 03:01 832344     /lib/tls/i686/cmov/
libc-2.4.so
b7f9e000-b7fa0000 r--p 0012c000 03:01 832344     /lib/tls/i686/cmov/
libc-2.4.so
b7fa0000-b7fa2000 rw-p 0012e000 03:01 832344     /lib/tls/i686/cmov/
libc-2.4.so
b7fa2000-b7fa6000 rw-p b7fa2000 00:00 0
b7fae000-b7fb0000 rw-p b7fae000 00:00 0
b7fb0000-b7fc9000 r-xp 00000000 03:01 833779     /lib/
ld-2.4.so
b7fc9000-b7fcb000 rw-p 00018000 03:01 833779     /lib/
ld-2.4.so
bfba6000-bfbbc000 rw-p bfba6000 00:00 0          [stack]
ffffe000-fffff000 ---p 00000000 00:00 0          [vdso]
Aborted (core dumped)
gli altri errori li ho corretti... consigli?

On Feb 17, 9:57 pm, Andrea Laforgia
<a.lafor...@andrealaforgia.it.invalid> wrote:

grazie :D
scusa non ti avevo letto!
voglio scrivere del codice che presi alcuni parametri, mi allochi
dinamicamente una matrice frastagliata di interi.
siete tutti gentilissimi.

vi spiego qual'è la mia consegna: devo trasformare un file di imput
del tipo:
in una matrice frastagliata di interi.
Vi posto il codice che ho scritto fin'ora.
Prima leggo il file e metto tutto in un vettore char.
Poi scanno questo char e dove ci sono numeri uso atoi e metto gli
interi nella colonna, e dove ci sono \n (a capo) genero una nuova riga
e riparto.
Terrei un solo vettore di interi usando un -1 come separatore di
righe, ma la consegna vuole che io sia in grado di leggere file con 20
milioni di cifre.
grazie
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
	char *c;
	FILE *in;
	int *p;
void legge ()
{
	int i=0, k=0;
	in= fopen("input.txt" , "r");
	for ( ; getc(in)!= EOF ; ) i++;
	c=(char *) malloc( i * sizeof(char));
	rewind(in);
	while ( k!=i ) c[k++]=fgetc(in);
}
/*codice sperimentale, non funziona, è la porzione che voglio che
metta i char nella matrice frastagliata di interi
Per ora mette tutto in un vettore
L'unico problema (piccolo offbyone) è che legge solo l'ultima cifra.
Lo sto riscrivendo
*/
void trasforma ()
{
	for(i=0; c[i]; i++)
	{
		if ( isdigit( c[i] ) && !isdigit( c[i-1] ) )
		{
		k++;
		p= realloc( p , k*sizeof(int) );
		p[k-1]=atoi( c+i );
		}
		else if ( c[i]== '\n')
		{
		k++;
		p= realloc( p , k*sizeof(int) );
		p[k-1]=-1;
		}
	}
}
int main () {
	int i;
	legge();
	trasforma();
	for(i=0; p[i]; i++) printf("%3d", p[i]);
	printf("\n");
return 0;
}
E ricordate: Gcc statement considered harmful.

mi sono dimenticato l'imput.txt
5 2 3 16 2
3
45

	*p=calloc(2, sizeof(char));
I commenti ai tuoi errori li leggi ?

 I commenti ai tuoi errori li leggi ?
...stai attento: p NON viene inizializzato, e questo è il problema
principale, ma se anche venisse inzializzato, stai allocando spazio
per 1 carattere utile per la prima stringa (2 = 1 carattere + '\0');
quello che mi hai detto tu...
scusa ma non lo capisco :(
vorrei solo un esempio pratico di una matrice frastagliata di char
generata dinamicamente con diverse frasi al suo interno...
tipo il comando per aumentare le righe... e il comando per aumentare
le colonne...
grazie mille e scusa la mia imbranataggine...

vorrei solo un esempio pratico 
Un esempio pratico significherebbe scriverti il programma, senza che
tu possa imparare nulla, cosa di cui non hai sicuramente bisogno,
vero ?

 le colonne...
Appunto, definisci un oggetto di tipo elemento_lista, che, oltre 
all'oggetto (o al puntatore all'oggetto medesimo), ha un puntatore 
all'elemento precedente e all'elemento successivo (oppure solo 
all'elemento successivo se non hai esigenza di scandire la lista anche 
all'indietro).
Un oggetto del tipo
struct elemento_lista
{
	void *oggetto;
	struct elemento_lista *prev;
	struct elemento_lista *next;
}
e per aggiungere un elemento alla lista, avendo uno
struct elemento_lista *last che punta sempre l'ultimo elemento
	struct elemento_lista *elem;
	if (elem = malloc(sizeof(*elem))
	{
		last->next = elem;
		elem->prev = last;
		last = elem;
		last->oggetto = quelloCheHaiLettoDalFile();


		last = elem;
Questo non va bene: nel caso del primo elemento, last non č
inizializzato e in ogni caso bisogna impostare elem->next a 0,
altrimenti non č possibile stabilire la fine della lista.
Un codice d'esempio (e sottolineo "d'esempio", ovvero scritto al volo,
inefficiente e possibilmente buggato :-)), č il seguente:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct nodeTag {
        int data;
        struct nodeTag* pNext;
} nodeT, *pNodeT;
pNodeT createNewNode(int aData) {
       pNodeT self = malloc(sizeof *self);
       if (self) {
          self->data = aData;
          self->pNext = 0;       
       }
       return self;
}
void listInsert(pNodeT *aHead, pNodeT node) {
     if (*aHead)
       listInsert(&((*aHead)->pNext), node);
     else 
       *aHead=node;
}
void listPrint(pNodeT aHead) {
     if (aHead) {
        printf("%d -> ", aHead->data);         
        listPrint(aHead->pNext);
     }
     else printf("(null)\n");
}
int main()
{
    pNodeT listHead=0;
    int i;
 
    srand(time(0));
 
    for (i=0; i<10; i++) 
      listInsert(&listHead, createNewNode(rand()%100));
 
    listPrint(listHead);  
    return 0;
}

il vostro codice è bello e intelligente....
ma io programmo da 3 mesi!
sono cose troppo complicate per me!
Provo a riformulare la domanda:
Io ho un puntatore di punatori di interi., cioè una matrice
frastagliata.
Mi fate un esempio della sintassi di realloc per aumentare il numero
di righe? e una per aumentare il numero di colonne?
grazie.

 e una per aumentare il numero di colonne?
Niet. Modello sbagliato. Le colonne meglio se le allochi una volta sola 
per riga.

di righe? 
La sintassi di realloc() è disponibile ovunque.
Cerca con Google "man realloc" e tanti auguri.

dati: rischioso...
Si può prevedere un record a lunghezza fissa oppure con separatore
(es.: la virgola).

ce l'o fatta.
Questo programma salva in un vettore *p gli interi, e in un vettore *a
gli accapo.
Vi spiego qual'è il mio problema: Il mio pc è vecchissimo (celeron 1.1
ghz con 128 mb di ram) e la lunghezza massima di un vettore è 10.000,
mentre sui pc moderni puo arrivare a 10 milioni.
Ho semplicemente spostato il problema.
Secondo me ci sono altre cose che non funzionano per colpa del pc, ma
non sono sicuro.
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
	char *c;
	FILE *in;
	int *p, *a;
void legge ()
{
	int i=0, k=0;
	in= fopen("input.txt" , "r");
	for ( ; getc(in)!= EOF ; ) i++;
	c=(char *) malloc( i * sizeof(char));
	rewind(in);
	while ( k!=i ) c[k++]=fgetc(in);
}
void trasforma ()
{
	int i, k=0, l, j, z=0;
	for(i=0; c[i]; i++)
	{
		if (isdigit( c[i] ))
		{
		j=i;
			for(l=i; ; l++)
			{
				if ( isdigit( c[l] ) &&  !isdigit( c[l+1] )  )
				{
					k++;
					i=l;
					break;
				}
			}
			p= realloc( p , k*sizeof(int) );
			p[k-1]=atoi(c+j);
		}
		if ( c[i] == '\n' )
		{
			z++;
			a= realloc( a , z*sizeof(int) );
			a[z-1]=k;
		}
	}
}
int main () {
	legge();
	trasforma();


 #include <math.h>
A che serve la math.h ?
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 			p= realloc( p , k*sizeof(int) );
realloc() non si usa MAI a questo modo: bisogna SEMPRE testare che la
riallocazione sia riuscita, quindi bisogna SEMPRE usare un puntatore di
appoggio, da assegnare a p nel caso non sia NULL, in modo da mettersi a
riparo da memory leak.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 nome alle variabili globali
Diciamo che è buona cosa evitare, per quanto possibile, variabili globali.
