2016-05-06 11 views
1

Ich habe versucht, die Adressen zu überprüfen und alles sieht normal aus, Druckarbeiten und alles andere funktioniert auch. Aber wenn es versucht, den Speicher freizugeben, stürzt das Programm ab. Code:C - freie Funktion stürzt ab

#include <stdio.h> 
#include <stdlib.h> 
#define FIRST_DIM 2 
#define SECOND_DIM 3 
#define THIRD_DIM 2 
#define TOTAL 12 
void getNums(float* pArr); 
void sortArr(float* pArr); 
void printArr(float* pArr); 
int main(void) 
{ 
    // Variable assignment 
    unsigned int i = 0, j = 0; 
    float*** pppArr = NULL; 

    // Memory assignment 
    pppArr = (float***)calloc(FIRST_DIM, sizeof(float**)); 
    if (!(pppArr)) 
    { 
     printf("Failed Allocating Memory..\n"); 
     system("PAUSE"); 
     return 1; 
    } 
    for (i = 0; i < FIRST_DIM; i++) 
    { 
     *(pppArr + i) = (float**)calloc(SECOND_DIM, sizeof(float*)); 
     if (!(*(pppArr + i))) 
     { 
      printf("Failed Allocating Memory..\n"); 
      system("PAUSE"); 
      return 1; 
     } 
    } 
    for (i = 0; i < FIRST_DIM; i++) 
    { 
     for (j = 0; j < SECOND_DIM; j++) 
     { 
      *(*(pppArr + i) + j) = (float*)calloc(THIRD_DIM, sizeof(float)); 
      if (!(*(*(pppArr + i) + j))) 
      { 
       printf("Failed Allocating Memory..\n"); 
       system("PAUSE"); 
       return 1; 
      } 
      printf("%p && %d\n", *(*(pppArr + i) + j), **(*(pppArr + i) + j)); 
     } 
    } 
    printf("ASD"); 
    // Getting numbers, sorting them and printing them out 
    getNums(**pppArr); 
    sortArr(**pppArr); 
    printArr(**pppArr); 

    // End of program 
    // Releasing memory 
    for (i = 0; i < FIRST_DIM; i++) 
    { 
     for (j = 0; j < SECOND_DIM; j++) 
     { 
      free(*(*(pppArr + i) + j)); 
     } 
    } 
    for (i = 0; i < FIRST_DIM; i++) 
    { 
     printf("%p\n", *(pppArr + i)); 
     free(*(pppArr + i)); 
    } 
    free(pppArr); 
    system("pause"); 
    return 0; 
} 

/* This function gets values for the given array from the user */ 
void getNums(float* pArr) 
{ 
    unsigned int i = 0; 
    for (i = 0; i < TOTAL; i++) 
    { 
     printf("Enter Number %d: ", i); 
     scanf("%f", pArr + i); 
     getchar(); 
    } 
} 

/* This function prints out the given array */ 
void printArr(float* pArr) 
{ 
    unsigned int i = 0; 
    for (i = 0; i < TOTAL; i++) 
    { 
     printf("Number %d: %.2f\n", i, *(pArr + i)); 
    } 
} 

/* This function sorts the given array from lowest to highest*/ 
void sortArr(float* pArr) 
{ 
    unsigned int i = 0, j = 0; 
    float temp = 0; 
    for (i = 0; i < TOTAL; i++) 
    { 
     for (j = 0; j < TOTAL - 1; j++) 
     { 
      if (*(pArr + j) > *(pArr + j + 1)) 
      { 
       temp = *(pArr + j); 
       *(pArr + j) = *(pArr + j + 1); 
       *(pArr + j+ 1) = temp; 
      } 
     } 
    } 
} 

gibt es fehlt etwas im?

+11

Oh nein, ein Drei-Sterne-Programmierer. – Downvoter

+4

Sie wissen, dass z.B. '* (pppArr + i)' ist das gleiche wie 'pppArr [i]'? Viele finden das letztere leichter zu lesen und zu verstehen (es sind auch ein paar Zeichen weniger zu schreiben). –

+2

[Dieser Link] (http://c2.com/cgi/wiki?ThreeStarProgrammer) erklärt @ Downvoters Kommentar. Es kann gelesen werden (zumindest das ist, was ich tue) als ein Vorschlag, diesen Code umzuformulieren, um es einfacher zu machen. – unwind

Antwort

2

Wenn Sie Zeiger und dynamische Zuordnung verwenden, wird der Speicher, den Sie zuweisen, höchstwahrscheinlich nicht zusammenhängend sein, aber Sie erhalten separate Speicherbereiche für jede Zuordnung. Das heißt, wenn Sie es als einen großen zusammenhängenden Speicherbereich in Ihren Funktionen behandeln, zeigen Sie undefined Verhalten.

Eine tatsächliche Array, wie

float arr[FIRST_DIM][SECOND_DIM][THIRD_DIM]; 

Nun dass wird zusammenhängend sein.

Siehe z.B. this old answer of mine für eine "grafische" Erklärung des Unterschieds zwischen Arrays von Arrays und Zeigern Zeiger.

+0

gibt es eine Möglichkeit, es zusammenhängend und auch im Heap allokiert zu machen? – Administrator

+0

@Administrator Ordnen Sie es als einen großen Chunk zu und verwenden Sie Zeigerarithmetik, um mit Indizes darauf zuzugreifen. (etwas wie zum Beispiel 'pArr [i * ROWS + j]', aber aktualisiert für Ihre spezifischen Bedürfnisse). –

0

Dieser Code indexiert außerhalb der Grenzen ziemlich stark. Der Speicher, der für pppArr reserviert ist, hat drei Ebenen der Indirektion. Es ist kein mehrdimensionales Array (d. H. Kein Array von Arrays), sondern ist ein Zeiger auf ein Array von Zeigern auf Arrays von Zeigern. Drei Ebenen der Indirektion. Es gibt 6 separate float Scheiben mit jeweils 2 zusammenhängenden Elementen (d. H. THIRD_DIM).

Wenn Sie getNums, sortArr und printArr aufrufen, übergeben Sie **pppArr. Dies entspricht der Übergabe von pppArr[0][0], die auf eine einzelne 2-Element-Sequenz von float Werten zeigt. Die Funktionen können nur auf THIRD_DIM Elemente zugreifen, d. H. 2. Stattdessen versuchen sie auf 12 Elemente zuzugreifen (d. H. TOTAL), was natürlich den Speicher korrumpiert und zu undefiniertem Verhalten führt.

Soweit ich das beurteilen kann, sieht es so aus, als ob Sie versuchen, auf den Speicher als ein eindimensionales Array zuzugreifen. Wenn ja, dann ist der einfachste Weg, um es zu beheben, 2 Ebenen der Umleitung zu beseitigen, und loswerden FIRST_DIM, SECOND_DIM und THIRD_DIM, und nur eine einzige, flache Array mit LENGTH Elemente zuweisen. Der Zeiger hätte den Typ float *.

+0

inb4 'aber Array und Zeiger sind das Gleiche!' –