Perché la dichiarazione dell'array non garantisce un'adeguata allocazione della memoria mentre malloc lo fa? [chiuso]

-2

In C ++, quando dichiaro una matrice come int array[10]; , a volte usa la memoria assegnata ad altre variabili dove questo problema è inesistente quando uso un puntatore intero e malloc per allocare memoria ad esso. Perché succede?

    
posta Abir Mukherjee 26.10.2014 - 15:41
fonte

2 risposte

6

Quindi penso che tu stia lavorando da una premessa sbagliata.

Credo che si presuma che se ci sono valori diversi da zero nello spazio di memoria che è stato appena assegnato che la memoria non è stata in qualche modo allocata correttamente. E questo è un presupposto terrificante che ti brucerà molto più tardi mentre costruisci programmi più complessi. Basti dire che la memoria è stata allocata correttamente, ma stai interpretando erroneamente ciò che hai ottenuto.

Né C né C ++ garantiscono che la memoria allocata sia inizializzata . La memoria (e le variabili) inizializzata è la memoria o le variabili che sono impostate su un valore specifico (tipicamente 0, "" o false ) quando la variabile è dichiarata o la memoria è allocata.

Quindi questo è dove penso che tu abbia una premessa sbagliata. Credo che tu stia guardando il contenuto della variabile assegnata di recente; vedere valori diversi da zero; e supponendo che l'allocazione sia andata storta.

Complicare le tue osservazioni è i due approcci che stai usando per allocare memoria.

int myArray[10];  // allocates on stack

int *myPointer;
myPointer = malloc(10*sizeof(int));  // allocates on heap

Come sottolineato nei commenti, un approccio alloca sullo stack e l'altro alloca dall'heap.

Assegnare dallo stack avrà più probabilità di riutilizzare lo spazio di memoria che è stato usato e rilasciato! da un'altra area in modo che la memoria non venga visualizzata come inizializzata.

L'allocazione dall'heap è probabilmente meno probabile che riutilizzi lo spazio che è già stato utilizzato e rilasciato in quanto è un'area di memoria più ampia da cui attingere. E c'è una netta possibilità che ti stai dimenticando di liberare la memoria dopo averla allocata, in modo da non incorrere in alcun caso di riutilizzo.

Indipendentemente da tutto ciò, la cosa corretta da fare in C e C ++ è inizializzare tutta la memoria e le variabili prima di usarlo. Prendi l'abitudine di chiamare immediatamente memset dopo aver allocato la memoria.

    
risposta data 26.10.2014 - 17:38
fonte
0

Sembra un overflow dello stack (hehe).

Quando si assegnano allo stack, ci sono altre entità presenti attorno all'array assegnato (nella memoria con un indirizzo immediatamente più grande dell'array). Dal momento che hai detto nel tuo commento "dopo poche iterazioni il valore di n cambia improvvisamente in qualcosa di spazzatura" presumo che n sia dichiarato nel tuo codice dopo l'array:

int array[10];
...
int n;

Non prima dell'array:

int n;
...
int array[10];

Questo non sembra un problema di "allocazione corretta della memoria", ma l'accesso alla matrice con un indice non valido e la scrittura in overflow. Penso che il tuo danneggiamento della memoria sia presente anche quando usi malloc, ma dato che non hai memoria allocata subito dopo l'array (quando usi malloc), il danneggiamento della memoria interessa aree di memoria non allocata (e questo non è visibile a te).

Ecco un esempio di overflow (e una supposizione spontanea da parte mia):

Dici di allocare array di n*n elementi e itera da 0 a n*n - 1 . Sei sicuro? Se usi due loop per loop, fai non fai questo:

for(int i = 0; i <=n; ++i) // this is incorrect
    for(int j = 0; j < n; ++j)
        // access at i, j

Ciò non itera n*n , ma [(n+1) * n] - 1 (e causerebbe un overflow).

    
risposta data 27.10.2014 - 10:44
fonte

Leggi altre domande sui tag