Allocazione dinamica vettore

di il
7 risposte

Allocazione dinamica vettore

Ciao a tutti, ho vari quesiti riguardo lo stesso esercizio, ringrazio in anticipo chi avesse la pazienza di aiutarmi
Il testo chiede di scrivere un programma che legga una sequenza di int (terminata da 0) e la stampi al contrario, allocando la memoria dinamicamente; non sapendo quanti int saranno inseriti devo ridimensionare il vettore che li contiene partendo da una dimensione piccola (es: 2) e raddoppiarla ogni volta che il vettore si riempie.

Io ho risolto con questo codice:

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

int main (void){
     int a[2], x=2, cont=0, *p, i;
     p=a;
     printf("Inserire una sequenza di interi terminata da 0: ");
     do{
          scanf("%d", &a[cont]); //inserisco l'int nel vettore predisposto
          cont++;
          if(cont==x){ //controllo se il vettore sia pieno
               x *= 2;
               p = (int *) malloc(x*sizeof(int));
          }
     }while(a[cont-1] != 0);

     cont -= 2;

     for(i=0; i<=cont; i++)
          printf("%d ", a[cont-i]); // stampo al contrario il vettore
     printf("\n");

     free(p);
     exit(0);
}
L'esecuzione mi sembra dia valori corretti, ma è la prima volta che mi cimento nell'allocazione dinamica in questo modo, e non vorrei che funzionasse tutto per qualche strana coincidenza fortunata .

I miei dubbi sono:
1) il codice (soprattutto nei dintorni della malloc) ha senso?
2) la "free(p);" è necessaria per un banale esercizietto come questo o serve solo per programmi "veri"?
3) perché senza la "exit(0)" il programma (capita solo con sequenze di 5 o più interi) stampa sia la sequenza rovesciata che il "\n", ma prima di terminare mi dà "Segmentation fault (core dumped)"?
4) ho provato ad adattare questo stesso programma a sequenze di char (ho cambiato solo i tipi e la condizione del while, che sia diverso da "\n") ma funziona bene solo con sequenze di massimo 5 caratteri. (con 6 ho bisogno di terminare 2 volte la sequenza (premendo 2 volte return) ma poi funziona, con 7 o più invece stampa la sequenza fino al posto del settimo inserito escluso (quindi settultimo ( ) da stampare), poi una serie di simboli misteriosi come pescati a caso dalla RAM, poi l'ultimo char e il resto della sequenza giusta. Faccio un esempio per chiarezza:
Input = abcdefghijklmno
Output = o n m l k j i h (serie di simboli strambi) o f e d c b a
Tutto questo sia con che senza la "exit(0)". Perché?

Sospetto fortemente che i quesiti 3 e 4 siano fortemente collegati dallo stesso errore, ma non ho idea di cosa sia.

Ho provato a stampare sia la "strlen" dei vari input, che il "cont" alla fine dell'inserimento, ed effettivamente anche loro testimoniano ci sia qualcosa di strano.. vi risparmio i risultati, se invece pensate che possano servire ve li scriverò.

7 Risposte

  • Re: Allocazione dinamica vettore

    Non è bene inserire più domande in un thread perché finisce che si fa confusione ...

    Comunque, parti da questi punti

    1) non si usa la malloc ma la realloc

    2) non si conclude il programma con la exit ma con la return

    3) la free va sempre usata

    Quando correggi, se ne riparla
  • Re: Allocazione dinamica vettore

    Chiedo venia! E' stata la foga di capire questo maledetto malfunzionamento.

    Grazie innanzitutto per la free.

    Purtroppo è specificato nel testo dell'esercizio che devo usare la malloc.
    Per quanto riguarda il "return", inizialmente non mettevo niente , poi ho provato con "return 0" (ma l'esito non cambiava), allora ho provato con exit(0) e si è risolto.
  • Re: Allocazione dinamica vettore

    Senza utilizzare la realloc() quando devi raddoppiare la dimensione del buffer puoi agire così:
    1) allochi un nuovo buffer di dimensione doppia (cont*2) in un puntatore diverso (esempio p2)
    2) copi dal vecchio (p) al nuovo buffer (p2) cont interi (usi memcpy() o fai un ciclo for)
    3) fai un free() del vecchio buffer (p) quindi setti p=p2 e prosegui
  • Re: Allocazione dinamica vettore

    Grazie candaluar, ora però ho un nuovo dubbio.. non sapendo in anticipo quante volte debba raddoppiare la dimensione, non penso sia una buona idea predisporre una serie di puntatori (p2, p3, p4...) pronti all'uso, quindi devo continuare ad alternare p e p2? (Se sì, non sono sicurissimo di avere un'idea di come farlo )

    Nel frattempo ho provato per sfizio con la realloc e funziona tutto come dovrebbe.
  • Re: Allocazione dinamica vettore

    Ovviamente si fa con la realloc nel "mondo reale".

    Se dovete fare esperienza con la malloc per "scopi didattici" allora ti bastano due puntatori, uno lo chiami p e sarà quello che punterà all'area effettivamente utilizzata, l'altro lo chiami ptmp e ti servirà per allocare la nuova area, passare i dati, assegnarlo a p. All'inizio p sarà NULL e userai ptmp per allocare l'area.
  • Re: Allocazione dinamica vettore

    quindi devo continuare ad alternare p e p2?
    Esatto! Se ti può aiutare, considera che p e p2 non sono "l' array", ma solo dei puntatori all'array (buffer): quindi quando fai p2=malloc() in p2 avrai il puntatore ad una nuova area di memoria in cui ci sono dati randomici, devi copiare i dati puntati da p nell'area puntata da p2; fatto questo l'area puntata da p non ti serve più, la deallochi e p ora punta ad un'area non allocata; facendo p=p2 fai in modo che p punti alla nuova area di dimensione raddoppiata, come se nulla fosse successo!
  • Re: Allocazione dinamica vettore

    Sì ... qualcosa come questi punti

    1) p = NULL;

    2) ptmp = malloc ...

    3) se p diverso da NULL

    copi da p a ptmp
    free di p

    4) p = ptmp
Devi accedere o registrarti per scrivere nel forum
7 risposte