2016-12-02 2 views
0

Ich bin neu in der dynamischen Zuordnung in c und ich bekomme Heap Korruption Fehler beim Aufruf der free() Funktion.Heap Korruption bei der Verwendung von free()

Der gesamte Code soll die Neuzuteilungsfunktion realloc() simulieren und es funktioniert gut bis zum Ende. Ich habe den Code im Debugger-Modus mehrmals ausgeführt und der Fehler erscheint am Ende. Wenn mir jemand helfen könnte, wäre ich sehr dankbar.

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


void realocare(int **v, int n,int m) 
{ 
    int *aux; 
    unsigned int i; 

    aux = (int*)malloc(m*sizeof(int)); 

    for (i = 0; i < m; i++) 
     aux[i] = v[i]; 

    *v = (int*)malloc(n*sizeof(int)); 

    for (i = 0; i < m; i++) 
     v[i] = aux[i]; 
    free(aux); 
} 

void afisare(int *v, int n,int i) 
{ 
    for (i = 0; i < n; i++) 
     printf_s("%d ", v[i]); 

     printf_s("\n"); 
} 

int main() 
{ 
    int *v; 
    unsigned int n,i,m; 

    scanf_s("%u", &n); 

    v = (int*)malloc(n*sizeof(int)); 

    for (i = 0; i < n; i++) 
     scanf_s("%d", &v[i]); 

    m = n; 
    printf("%d", m); 
    afisare(v, n, i); 
    n++; 
    realocare(&v, n,m); 
    v[n - 1] = 9000; 
    afisare(v, n, i); 

    free(v); 
    return 0; 
} 
+0

[Bitte lesen Sie diese Diskussion darüber, warum der Rückgabewert von 'malloc()' und Familie in 'C' nicht umgewandelt werden soll.] (Http://stackoverflow.com/q/605845/2173917). –

+0

Hinweis: siehe 'realocare (v, n, m);' –

+1

bei 'realocare':' v = (int *) malloc (n * sizeof (int)); ': Es ändert nicht die Variable auf dem Aufrufer Seite. – BLUEPIXY

Antwort

2

Sie zu vn Elementen zuordnen

v = ... malloc(n*sizeof(int)); 

und m

for (i = 0; i < m; i++) 
    v[i] = aux[i]; 

Für den Fall zuweisen, dass m größer dann n ist: Handeln schreibt so ungültigen Speicher, und mit diesem ruft undefiniertes Verhalten auf, so dass von diesem Moment an alles passieren kann.

In Ihrem partikulären Fall höchstwahrscheinlich dies vermasselt interne Speicherverwaltung Strukturen, was den Fehler einen späteren Aufruf an free().


Änderungen an einer Variablen durchgeführt, die an eine Funktion übergeben worden sind nicht vom Anrufer reflektiert, wie die Funktion in C immer und immer erhält nur eine Kopie dessen, was der Anrufer weitergegeben.

zum Beispiel also der neue Wert, den Sie v zugewiesen bleibt unbekannt an den Aufrufer von realocare().

Sie können dieses Problem beheben, indem Sie den Code Einstellung wie folgt:

void realocare(int **ppv, int n, int m) //reallocation simulation function 
{ 
    int *aux; 
    unsigned int i; 

    aux = malloc(m*sizeof(int)); 

    for (i = 0; i < m; i++) 
    aux[i] = (*ppv)[i]; 

    free(*ppv); // Free what you had, to not leak this memory. 

    *ppv = malloc(n*sizeof(int)); 

    for (i = 0; i < m; i++) 
    (*ppv)[i] = aux[i]; 

    free(aux); 
} 

Und es so nennen:

realocare(&v, n, m); 

Ihr Code verwendet zwei Anrufe malloc() und zwei Anrufe free() . Dies ist ineffizient.

Blick auf die folgenden (Hinzufügen einiger anderer nicht nur kosmetische Änderungen):

void realocare(int **ppv, size_t n, size_t m) // no need for negative sizes ... 
{ 
    int * aux = malloc(n * sizeof *aux); 
    size_t i = 0; // no need for negative counters ... 

    for (;i < m; ++i) 
    { 
    aux[i] = (*ppv)[i]; 
    } 

    free(*ppv); 

    *ppv = aux; 
} 

Nur ein malloc und ein free ... :-)


Und der Vollständigkeit halber eine robuste Version :

int realocare(int **ppv, size_t n, size_t m) 
{ 
    int result = -1; // be pessimistic 

    if (NULL == ppv) 
    { 
    errno = EINVAL; 
    } 
    else 
    { 
    int * aux = malloc(n * sizeof *aux); 

    if (NULL != aux) 
    { 
     size_t i = 0; 

     for (;i < m; ++i) 
     { 
     aux[i] = (*ppv)[i]; 
     } 

     free(*ppv); 

     *ppv = aux; 

     result = 0; // return success! 
    } 
    } 

    return result; 
} 

Nennen sie es wie folgt aus:

#include <stdlib.h> 
#include <stdio.h> 
#include <errno.h> // for errno 

... 

int main(void) 
{ 
    ... 

    if (-1 == realocare(&v, n, m)) 
    { 
    perror("realocare() failed"); 
    exit(EXIT_FAILURE); 
    } 
+0

danke, aber ich bin nicht sicher, ob ich es herausgefunden habe, habe ich die folgenden Änderungen, aber es funktioniert immer noch nicht: 'void realocare (int *** v, int n, int m)', '* v = (int *) malloc (n * sizeof (int)); 'realocare (& v, n, m);' – rednefed

+0

@refüfed: Bitte sehen Sie meine aktualisierte Antwort. – alk

+0

danke mein mann, ich wusste wirklich nicht die (* ppv) teil – rednefed

Verwandte Themen