2017-01-30 3 views
2

Я пытаюсь реализовать простую программу, используя файл заголовка, где функция в файле заголовка принимает массив int и возвращает массив int.Возвращение массива из функции в C: Ошибка сегментации

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]); 
    } 

} 

Я получаю ошибку сегментации в цикле печати в test.c.

Может ли кто-нибудь помочь?

+0

Массив внутри 'point()' выходит из области действия и уничтожается сразу после возвращения функции. Вместо этого создайте массив в 'main()' и передайте ему указатель в качестве аргумента. – HolyBlackCat

+0

Вы возвращаете адрес массива, созданного в стеке, а затем уничтожаетесь в конце функции. Время жизни массива с именем array слишком короткое. Массив не существует после завершения функции с именем point. –

+0

Создание массива 'int array [4]' создаст этот массив в стеке. Затем вы выходите из метода, вся память, связанная с этим методом, получает вызов (за исключением возвращаемого значения), а возвращаемый указатель указывает на позицию в стеке, которая больше не существует. – Paul

ответ

2

Проблема связана с областью переменной array, которую вы возвращаете в своем методе. Прямо сейчас вы возвращаете array, локальную переменную, определенную в методе, point. Однако, как только point будет завершен, все локальные переменные в функциональном кадре, включая array, будут удалены из основной памяти. Так что, хотя вы все еще получаете адрес памяти от point, не известно, что может быть на этом адресе памяти. Поэтому обработка array в виде массива int при распечатке его элементов приведет к ошибке сегментации.

Мое предложение исправить это, чтобы выделить память из кучи, используя malloc, так что array длится вне рамки point. Решение должно выглядеть так:

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

Вы не можете возвращать массивы из функций. Когда возвращается point(), локальный массив внутри этой функции выходит за пределы области видимости. Этот массив создается в стеке и будет уничтожен после завершения функции. Вся связанная с ним память отбрасывается, а возвращаемый указатель указывает на позицию в стеке, которая больше не существует. Вам нужно вместо этого выделить указатель на кучу и вместо этого вернуть это. Это позволяет использовать array в вашей программе.

Вместо:

int array[4]; 

вам необходимо динамически выделять указатель с помощью malloc():

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

malloc() выделяет запрошенные память в куче, и возвращает void* указатель на него.

Примечание:malloc() может вернуться NULL при неудачной, поэтому он должен быть всегда проверять. Вам также необходимо указать free() любую память, ранее выделенную malloc(). Вы также don't need to cast return of malloc().

Еще одна вещь, указывающая на использование магического номера 4 по всей вашей программе. Это действительно должно быть рассчитано с использованием sizeof(a)/sizeof(a[0]).

Вы можете объявить это как size_t переменные в main():

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

Или вы можете использовать макрос:

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

И просто позвоните ARRAYSIZE(a) каждый раз вы хотите, чтобы размер массива.

0

Вы можете определить массив [] как глобальную переменную или динамически распределить память для него, как указано в приведенных выше комментариях, используя malloc(). Поскольку массив [] выделяется в функции function(), он удаляется после завершения функции. Следовательно, ссылка на возвращаемый указатель вызывает ошибку сегментации.

Смежные вопросы