PDA

Visualizza la versione completa : [C] - Allocazione dinamica


Napoli82
16-12-2003, 00:26
Ciao ragazzi!

Qualcuno saprebbe dirmi perchè in C sè alloco un array con malloc (o anche con calloc) all'interno di una funzione, alla prima esecuzione di tale funzione tutto fila liscio, mentre alla seconda appena esegue l'istruzione malloc parte un errore di run-time e cade il programma?

Preciso che prima che la funzione in questione termini, questa dealloca l'array tramite free.

Confido in voi...

Bye

Johnny_Depp
16-12-2003, 03:22
Originariamente inviato da Napoli82
alla prima esecuzione di tale funzione tutto fila liscio, mentre alla seconda...
perchè quasi sicuramente allochi male la memoria sin dall'inizio
e se il programma non crasha subito (alla prima allocazione)
è solamente per pura casualità.

posta il codice.

Napoli82
16-12-2003, 10:36
Allora, il codice è:

double FUNZIONE(int n, float *x, float *y, float pt)
{
double *S,*B,*H,*G,val;
int intervallo;
B=(double *)malloc(n*sizeof(double));
H=(double *)malloc(n*sizeof(double));
S=(double *)malloc(4*sizeof(double));
G=(double *)malloc(n*sizeof(double));
Coeff_F(n,x,H,B);
Coeff_G(n,y,H,G);
G[0] = 0.0;
G[n] = 0.0;
Gauss(n,H,B,G);
BackSub(n,H,B,G);
intervallo=Ric_Bin(n,pt,x);
Coeff_Spline(intervallo,S,y,H,G);
val=Horner_Spline(x[intervallo],pt,S);
free(S);
free(B);
free(H);
free(G);
return val;
}

void main(void)
{
...................................
X=(float *)malloc(n*sizeof(float));
Y=(float *)malloc(n*sizeof(float));
....................................
....................................
do
{
printf("\nInserire pt: ");
scanf("%lf",&pt);
valutazione=FUNZIONE(n,X,Y,pt);
printf("\nIl valore di S(pt) e' : %lf\n",valutazione);
printf("\nValutare S in un altro punto? (si=1/no=0) ");
scanf ("%d",&quit);
}while(quit!=0);
free(X);
free(Y);
.................................................. ...........
}

Essendo la chiamata a FUNZIONE in un ciclo do-while, questa può essere ripetuta ovviamente più di una volta: alla seconda esecuzione, al momento della prima allocazione (quindi "B=(double *)malloc(n*sizeof(double));") il programma cade.

Grazie per l'aiuto.

Johnny_Depp
16-12-2003, 12:45
mah :master:

la "singola" allocazione/deallocazione non mi sembra errata...

anche se non ho capito:

a cosa serve allocare dinamicamente "n" (visto che non viene chiesto di immetterla) in X e Y in main()... e poi la funzione che hai postato chiama altre 4/5 funzioni e sicuramente l'errore si verifica in una di queste.

Napoli82
16-12-2003, 13:18
a cosa serve allocare dinamicamente "n" (visto che non viene chiesto di immetterla) in X e Y in main()...

Non ho riportato tutto il main(), n è immessa dall'utente da tastiera.


la funzione che hai postato chiama altre 4/5 funzioni e sicuramente l'errore si verifica in una di queste

Ok, potrebbe anche darsi, ma qualsiasi cosa facciano le 4/5 funzioni che vengono chiamate il fatto che prima di uscire gli array vengano deallocati con free non dovrebbe riportare tutto allo stato iniziale e quindi pronto per la prossima allocazione-esecuzione?

Johnny_Depp
16-12-2003, 13:36
ho provato con il seguente test:

#include <stdio.h>
#include <stdlib.h>

double FUNZIONE(int n, float *x, float *y, float pt)
{
double *S,*B,*H,*G,val;
int intervallo;
B=(double *)malloc(n*sizeof(double));
H=(double *)malloc(n*sizeof(double));
S=(double *)malloc(4*sizeof(double));
G=(double *)malloc(n*sizeof(double));
//Coeff_F(n,x,H,B);
//Coeff_G(n,y,H,G);
G[0] = 0.0;
G[n] = 0.0;
//Gauss(n,H,B,G);
//BackSub(n,H,B,G);
//intervallo=Ric_Bin(n,pt,x);
//Coeff_Spline(intervallo,S,y,H,G);
//val=Horner_Spline(x[intervallo],pt,S);
free(S);
free(B);
free(H);
free(G);
return val;
}



int main()
{
int n=2, quit;
float *X, *Y, pt;
double valutazione;

X=(float *)malloc(n*sizeof(float));
Y=(float *)malloc(n*sizeof(float));

do
{
printf("\nInserire pt: ");
scanf("%lf",&pt);
valutazione=FUNZIONE(n,X,Y,pt);
printf("Il valore di S(pt) e':\n%.2lf\n",valutazione);
printf("\nValutare S in un altro punto? (si=1/no=0) ");
scanf ("%d",&quit);
} while(quit!=0);

free(X);
free(Y);

system("pause");
return 0;
}
Nel seguente modo si verificano 0 errori di allocazione... anche se ovv. il risultato sarà nullo.

Napoli82
16-12-2003, 14:55
Ho fatto anch'io così:

double FUNZIONE(int n, float *x, float *y, float pt)
{
double *S,*B,*H,*G,val;
int range;
B=(double *)malloc(n*sizeof(double));
H=(double *)malloc(n*sizeof(double));
S=(double *)malloc(4*sizeof(double));
G=(double *)malloc(n*sizeof(double));
//Coeff_F(n,x,H,B);
//Coeff_G(n,y,H,G);
G[0] = 0.0;
G[n] = 0.0;
//Gauss(n,H,B,G);
//BackSub(n,H,B,G);
//range=Ric_Bin(n,pt,x);
//Coeff_Spline(range,S,y,H,G);
//val=Horner_Spline(x[range],pt,S);
free(S);
free(B);
free(H);
free(G);
return val;
}

int main(void)
{
int n=2, quit;
float *X, *Y, pt;
double valutazione;

X=(float *)malloc(n*sizeof(float));
Y=(float *)malloc(n*sizeof(float));

do
{
printf("\nInserire pt: ");
scanf("%lf",&pt);
valutazione=FUNZIONE(n,X,Y,pt);
printf("\nIl valore di S(pt) e' : %lf\n",valutazione);
printf("\nValutare S in un altro punto? (si=1/no=0) ");
scanf ("%d",&quit);
}while(quit!=0);
free(X);
free(Y);
return 0;
}

e si, è vero non dà più errore d'allocazione, ma prova a cambiare n=2 con n=5 e siamo punto e a capo.
Questo tra l'altro "scagiona" le altre funzioni visto che ora non vengono proprio richiamate, giusto?
E poi, con n=2 sai quand'è che da errore? All'ultima riga del main, su free(Y).

I misteri della programmazione...

Johnny_Depp
16-12-2003, 15:32
a me non da errore ne con 2, ne con 5... (ho provato anche con Linux che ha un compilatore pignolo)

se ti va posta l'intero codice (magari commentando i vari passaggi)

e inserisci il codice tra i TAG [C O D E] e [/C O D E]
senza gli spazi fra una lettera e l'altra...

così facendo rendi il codice indentato (quindi più leggibile)

Napoli82
16-12-2003, 15:38
Non posso postre tutto il codice, semplicemente perchè non c'entra!

Se in privato mi lasci l'email magari te lo invio.

Cmq grazie davv. per l'interessamento...

Johnny_Depp
16-12-2003, 15:44
http://forum.html.it/forum/member.php?s=&action=mailform&userid=40871

p.s. commenta il codice, altrimenti non capisco cosa deve fare.

Loading