Malloc in einem Funktionsaufruf erscheint auf Rückkehr immer befreit zu werden?

StackOverflow https://stackoverflow.com/questions/105477

  •  01-07-2019
  •  | 
  •  

Frage

Ich glaube, ich habe es bis auf den einfachsten Fall:

int main(int argc, char ** argv) {
  int * arr;

  foo(arr);
  printf("car[3]=%d\n",arr[3]);
  free (arr);
  return 1;
}

void foo(int * arr) {
  arr = (int*) malloc( sizeof(int)*25 );
  arr[3] = 69;
}

Der Ausgang ist dies:

> ./a.out 
 car[3]=-1869558540
 a.out(4100) malloc: *** error for object 0x8fe01037: Non-aligned pointer
                         being freed
 *** set a breakpoint in malloc_error_break to debug
>

Wenn jemand beleuchten kann, wo mein Verständnis versagt, würde es sehr zu schätzen.

War es hilfreich?

Lösung

Sie übergeben die Zeiger nach Wert, nicht Bezug genommen wird, so was auch immer Sie tun, mit arr innerhalb foo werden keinen Unterschied außerhalb der foo-Funktion machen. Als m_pGladiator schrieb eine Möglichkeit, eine Referenz zu erklären ist wie diese Zeiger (. Nur in C ++ btw C nicht weiß, über Referenzen):

int main(int argc, char ** argv) {
  int * arr;

  foo(arr);
  printf("car[3]=%d\n",arr[3]);
  free (arr);
  return 1;
}

void foo(int * &arr ) {
  arr = (int*) malloc( sizeof(int)*25 );
  arr[3] = 69;
}

Eine andere (bessere imho) Weg ist, den Zeiger nicht als Argument übergeben, sondern einen Zeiger zurück:

int main(int argc, char ** argv) {
  int * arr;

  arr = foo();
  printf("car[3]=%d\n",arr[3]);
  free (arr);
  return 1;
}

int * foo(void ) {
  int * arr;
  arr = (int*) malloc( sizeof(int)*25 );
  arr[3] = 69;
  return arr;
}

Und Sie können einen Zeiger auf einen Zeiger übergeben. Das ist die Art und Weise C durch Verweis übergeben. Verkompliziert die Syntax ein wenig, aber gut - das ist, wie C ist ...

int main(int argc, char ** argv) {
  int * arr;

  foo(&arr);
  printf("car[3]=%d\n",arr[3]);
  free (arr);
  return 1;
}

void foo(int ** arr ) {
  (*arr) = (int*) malloc( sizeof(int)*25 );
  (*arr)[3] = 69;
}

Andere Tipps

Sie haben arr in foo zugewiesen, aber der Zeiger-Wert wird in dem Call-Stack gespeichert. Wenn Sie dies tun wollen, mag es so aus:

void foo( int ** arr) {
    *arr = (int *)malloc( sizeof(int) * 25 );
    (*arr)[3] = 69;
}

Und in Haupt, übergeben Sie einfach einen Zeiger auf foo (wie foo (& arr))

foo erhält eine lokale Kopie des int-Zeiger, alloactes Speicher zu ihm und leckt, dass der Speicher, wenn es außerhalb des Gültigkeitsbereichs geht.

Eine Möglichkeit, dies zu beheben foo bekommen Sie den Zeiger zurück:

int * foo() {
  return (int*) malloc( sizeof(int)*25 );
}

int main() {
    int* arr = foo();
}

Ein weiterer Grund ist foo einen Zeiger auf einen Zeiger auf geben

void foo(int ** arr) {
   *arr = malloc(...);
}

int main() {
    foo(&arr);
}

In C ++ ist es einfacher foo zu modifizieren, um einen Verweis auf einen Zeiger zu akzeptieren. Die einzige Änderung, die Sie in C ++ benötigen ist foo

zu ändern
void foo(int * & arr)

Da Ihr den Zeiger nach Wert sind vorbei, die arr Zeiger in Haupt verweist nicht auf den zugewiesenen Speicher. Das bedeutet, zwei Sache: Sie haben ihnen ein Speicherleck (NO, wird der Speicher nicht freigegeben, nachdem die Funktion foo abgeschlossen ist), und wenn Sie den arr Zeiger in Haupt zugreifen Sie einigen beliebigen Speicherbereich zugreifen, damit Sie don ‚t get 3 ausgedruckt und somit frei () weigert sich zu arbeiten. Sie Glück haben, nicht einen Segmentation Fault bekommen haben beim Zugriff auf arr [3] innerhalb des Haupt.

Sie können nicht den Wert Ihres Argument ändern (arr), wenn sie als Referenz übergeben wird nicht in (&). In der Regel würden Sie den Zeiger zurück, so sollten Sie Ihre Methode:

arr = foo ();

Es ist schlimm juju zu versuchen Argumente neu zuzuweisen; Ich weiß nicht empfehlen, die (&) Lösung.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top