我正在尝试使用头文件实现一个简单的程序,其中头文件中的函数接受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
。