从C:Segmentation Fault中的函数返回数组



我正在尝试使用头文件实现一个简单的程序,其中头文件中的函数接受int数组并返回int数组。

header.h:中

int* point(int a[]);

header.c:中

#include<stdio.h>
#include "header.h"
int* point(int a[])
{
printf("In the point functionn");
int array[4],i;
for(int i=0;i<4;i++)
{
printf("%dth Iterationn",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 functionn");
array=point(a);
printf("Back in the main functionn");
for(i=0;i<4;i++)
{
//SEGMENTATION FAULT HERE
printf("%dn",array[i]);
}
}

我在test.c的打印循环中遇到分段故障。

不能从函数返回数组。当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()分配的任何内存。您也不需要强制转换malloc()的return。

需要指出的另一件事是在整个程序中使用幻数4。这实际上应该使用sizeof(a)/sizeof(a[0])来计算。

您可以在main():中将其声明为size_t变量

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

或者你可以使用一个宏:

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

每当您想要数组的大小时,只需调用ARRAYSIZE(a)即可。

问题与方法中返回的array变量的作用域有关。现在您返回的是array,一个在方法point中定义的局部变量。然而,一旦point完成执行,包括array在内的函数帧内的所有局部变量将从主存储器中丢弃。因此,即使你仍然从point中得到一个内存地址,也不知道这个内存地址可能是什么。因此,当打印出array的元素时,将其视为int数组将导致分割错误。

我的建议是使用malloc从堆中分配内存,以便array持续在point的帧之外。解决方案应该是这样的,

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

您可以将array[]定义为全局变量,也可以使用malloc()为其动态分配内存,如以上注释中所述。由于array[]是在函数point()中分配的,因此一旦函数退出,它就会被删除。因此,对返回指针的引用会导致segmentation fault

相关内容

  • 没有找到相关文章

最新更新