2017-01-30 9 views
2

Ich versuche, ein einfaches Programm mit einer Header-Datei zu implementieren, wo eine Funktion in der Header-Datei ein int-Array akzeptiert und auch ein int-Array zurückgibt.Rückgabe eines Arrays von einer Funktion in C: Segmentierung Fehler

header.h

int* point(int a[]); 

header.c

#include<stdio.h> 
#include "header.h" 

int* point(int a[]) 
{ 
printf("In the point function\n"); 
int array[4],i; 
for(int i=0;i<4;i++) 
{ 
    printf("%dth Iteration\n",i); 
    array[i]=a[i]; 
} 

return array; 
} 

test.c

#include<stdio.h> 
#include "header.h" 
void main() 
{ 
int *array,i; 
    int a[]={1,2,3,4}; 
    printf("calling point function\n"); 
    array=point(a); 
    printf("Back in the main function\n"); 
    for(i=0;i<4;i++) 
    { 
    //SEGMENTATION FAULT HERE 
    printf("%d\n",array[i]); 
    } 

} 

ich an der Druckschleife in test.c einen Segmentation Fault bin immer.

Kann jemand helfen?

+0

Das Array innerhalb des 'point()' geht außerhalb des Bereichs und wird zerstört, sobald die Funktion zurückkehrt. Erstellen Sie stattdessen das Array in 'main()' und übergeben Sie ihm einen Zeiger als Argument. – HolyBlackCat

+0

Sie geben die Adresse eines Arrays zurück, das auf dem Stapel erstellt und dann am Ende der Funktion zerstört wurde. Die Lebensdauer des Arrays namens array ist zu kurz. Das Array existiert nicht, nachdem die Funktion namens point abgeschlossen wurde. –

+0

Das Erstellen eines 'int array [4]' erstellt dieses Array auf dem Stack. Wenn Sie die Methode beenden, geht der gesamte mit diesem Methodenaufruf verknüpfte Speicher verloren (mit Ausnahme des zurückgegebenen Werts), und der zurückgegebene Zeiger zeigt auf eine Position auf dem Stapel, die nicht mehr vorhanden ist. – Paul

Antwort

2

Das Problem hat mit dem Umfang der Variable zu tun, die Sie in Ihrer Methode zurückgeben. Im Moment geben Sie , eine lokale Variable, die in der Methode point definiert ist, zurück. Sobald die Ausführung von point beendet ist, werden alle lokalen Variablen innerhalb des Funktionsrahmens einschließlich array aus dem Hauptspeicher gelöscht. Obwohl Sie immer noch eine Speicheradresse von point erhalten, können Sie nicht sagen, was an dieser Speicheradresse sein könnte. Wenn Sie deshalb array als int-Array behandeln, wenn Sie seine Elemente drucken, führt dies zu einem Segmentierungsfehler.

Mein Vorschlag, dies zu beheben, ist die Zuweisung von Speicher aus dem Heap mit malloc, so dass array außerhalb des Rahmens von point dauert. Die Lösung sollte wie folgt aussehen:

int* point(int a[]) 
{ 
printf("In the point function\n"); 
int *array = (int *) malloc(4 * sizeof(int)); //dynamically allocate memory for 4 integers 
int i; 
for(i=0;i<4;i++) 
{ 
    printf("%dth Iteration\n",i); 
    array[i]=a[i]; 
} 

return array; 
} 
2

Sie können Arrays nicht aus Funktionen zurückgeben. Wenn point() zurückkehrt, wird das lokale Array innerhalb dieser Funktion nicht mehr verwendet. Dieses Array wird auf dem Stapel erstellt und wird zerstört, sobald die Funktion beendet ist. Der gesamte damit verbundene Speicher wird verworfen, und der zurückgegebene Zeiger zeigt auf eine Position auf dem Stapel, die nicht mehr existiert. Sie müssen stattdessen einen Zeiger auf den Heap zuweisen und diesen stattdessen zurückgeben. Dies ermöglicht in Ihrem Programm geteilt werden.

Statt:

int array[4]; 

müssen Sie dynamisch einen Zeiger zuzuweisen malloc() mit:

int *array = malloc(4 * sizeof(*array)); /* or sizeof(int) */ 
if (array == NULL) { 
    /* handle exit */ 
} 

malloc() zuordnet Speicher auf dem Heap angefordert wird, und gibt einen void* Zeiger darauf.

Hinweis:malloc() kann NULL zurück, wenn nicht erfolgreich, so muss es immer überprüft werden. Sie müssen auch free() Speicher, der zuvor von malloc() zugewiesen wurde. Sie auch don't need to cast return of malloc().

Eine weitere Sache, auf die Sie hinweisen sollten, ist die Verwendung der magischen Nummer 4 in Ihrem gesamten Programm. Dies sollte wirklich unter Verwendung sizeof(a)/sizeof(a[0]) berechnet werden.

Sie können in Ihrem main() dies als size_t Variable deklarieren:

size_t n = sizeof(a)/sizeof(a[0]); 

Oder Sie können ein Makro verwenden:

#define ARRAYSIZE(arr) (sizeof(arr)/sizeof(arr[0])) 

Und rufen Sie einfach ARRAYSIZE(a) jedes Mal wenn Sie die Größe des Arrays werden soll.

0

Sie können entweder array [] als globale Variable definieren oder dynamisch Speicher zuweisen, wie in den obigen Kommentaren mit malloc() erwähnt. Da array [] im Funktionspunkt() zugewiesen wird, wird es gelöscht, sobald die Funktion beendet wird. Daher verursacht eine Referenz auf den zurückgegebenen Zeiger einen Segmentierungsfehler.

Verwandte Themen