PDA

View Full Version : [C] Problemino con gli array dinamici


Negative_creep
09-02-2008, 11:44
Ciao a tutti, volevo provare a utilizzare i puntatori come array dinamici e ho creato questo programma semplice dove si inseriscono dei numeri fin tanto che non gli si dà una parola diversa da "si". Ogni intero viene inserito nella posizione *(numeri+j) ma non riesco a capire come mai il programma al termine crasha (esce un messaggio di errore di windows) ma soprattutto non riesco a capire perchè se decido di stampare il numero in posizione *numeri mi stampa 0 sempre...
Grazie per ogni eventuale aiuto...:)


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

int main(void) {
int i,n,j=0;
int *numeri;
char s[2]= "si";
numeri = (int*)malloc(sizeof(int));
do {

printf("Inserisci un numero:");
scanf("%d",&n);
*(numeri+j) = n;
printf("Vuoi inserirne un altro? |SI| |NO| ");
scanf("%s", &s);
j++;

}
while(strcmp(s,"si")==0);
realloc(numeri, (sizeof(int)*j)+4);

printf("I numeri inseriti sono: %d \n ",j);
for (i=0;i<j;i++){
printf("%d) %d \n",i+1,*(numeri+i));
}

}

gugoXX
09-02-2008, 11:58
Ma la realloc non devi metterla dentro il ciclo?

Negative_creep
09-02-2008, 12:52
Non penso...comunque anche mettendola dentro il ciclo dà stesso errore...:(

gugoXX
09-02-2008, 12:59
Ma come non penso.
Ogni volta che aggiungi un numero devi riallocare no? E' questo l'esercizio, altrimenti cosa riallochi a fare alla fine.
Ti serve lo spazio gia' mentre aggiungi i numeri alla lista.
E poi tieni conto che la realloc puo' restituire errore se non riesce a riallocare.
Ah, invece di
*(numeri+J)=n;
metti
numeri[j]=n;

la prima mi sa che e' sbagliata, nel senso che almeno dovresti scrivere
*(numeri + j*sizeof(int)) = n;
ma fa pena a leggersi...

cionci
09-02-2008, 13:17
L'aritmetica dei puntatori fa spostamenti in base al tipo di puntatore.
Quindi se hai

int *i:

*(i + 1) punta all'elemento successivo (cioè sizeof(int) byte dopo).

In ogni caso il problema è proprio che realloc deve essere inserito nel ciclo e deve avere parametro di dimensione pari a sizeof(int) * j.

gugoXX
09-02-2008, 13:21
L'aritmetica dei puntatori fa spostamenti in base al tipo di puntatore.
Quindi se hai

int *i:

*(i + 1) punta all'elemento successivo (cioè sizeof(int) byte dopo).


Hai ragione. Ho riletto un appunto ed hai ragione. Sono anni che non vedo il C.

Resta che personalmente preferisco leggere
numeri[j]=i;
invece che
*(numeri+j)=i;

cionci
09-02-2008, 13:23
Pure io ;)

Negative_creep
10-02-2008, 08:08
Grazie gugoXX e Cionci, oggi non riesco a modificare il programma comunque appena posso lo riprovo a compilare con i vostri suggerimenti, posto solo per dirvi grazie!


P.S. Ogni volta che aggiungi un numero devi riallocare no? E' questo l'esercizio, altrimenti cosa riallochi a fare alla fine.

non è che è un esercizio, mi è venuto in mente di fare una cosa del genere ed ho provato. Mi potresti dire cosa intendi per riallocare?Dovrei farlo per ogni numero nell'array?perchè il comando realloc l'ho trovato su internet visto che non mi funzionava normalmente..

gugoXX
10-02-2008, 08:39
Allora, un programma deve dire al sistema operativo (per farla breve) di quanta memoria ha bisogno per i suoi dati.
E questo e' il tuo primo comando malloc
lanci la malloc(xx), dove xx e' il numero di byte di cui hai bisogno.
To hai lanciato malloc(sizeof(int))
ovvero hai detto al sistema opeartivo di riservati una zona di memoria sufficiente per farle contenere un intero, un solo numero.

Se durante il ciclo conti di aggiungere altri numeri alla tua lista, allora dovrai dire al sistema operativo di riallocare la tua zona di memoria, estendendola.

Mi potresti dire cosa intendi per riallocare?Dovrei farlo per ogni numero nell'array

Ovviamente no. Potresti per esempio progettare il tuo programma affinche' funzioni solo fino a 50 numeri. Allocherai quindi gia' subito tutta la memoria all'inizio
malloc( 50 * sizeof(int) )
E dentro al ciclo dovrai controllare solo di non farne mettere mai piu' di 50.
Senza riallocare piu'.

Ah, ancora una cosa.
Alla fine di tutto devi dire al sistema operativo che la memoria che hai allocato non ti serve piu'.
Altrimenti fai la fine di quei programmi che "mangiano" la memoria e se la tengono anche quando vengono chiusi.
La funzione dovrebbe essere
free
ma e' meglio che cerchi o che aspettiamo qualcuno, dato che il C non lo vedo davvero da almeno 10 anni.