我一直在为电磁模拟课程编写一段代码,但我遇到了一个问题。我决定通过将原始计算扩展到最多10 ^ 8个元素的真正大网格来做一些额外的工作,所以现在我必须使用malloc()。
到目前为止,这么好,但由于我更喜欢将代码保存在库中,然后使用编译器的内联选项进行编译,我需要一种在函数之间传递信息的方法。因此,我开始使用结构来跟踪网格的参数,以及指向信息数组的指针。我通过以下方式定义了结构:
typedef struct {
int height;
int width;
int bottom; //position of the bottom node
unsigned int*** dat_ptr;//the pointer to the array with all the data
} array_info;
指向unsigned int的三重指针是指向2D数组的指针。我必须这样做,因为否则它是通过值传递的,我不能在函数内改变它。
现在,当我尝试使用以下函数为结构分配内存时:
void create_array(array_info A)//the function accepts struct of type "array_info" as argument
{
int i;
unsigned int** array = malloc(sizeof(*array) * A.height);//creates an array of arrays
for(i = 0; i<A.height; ++i)
{
array[i] = malloc(sizeof(**array) * A.width);//creates an array for each row
}
*A.dat_ptr=array;//assigns the position of the array to the input pointer
}
执行操作时出现分段错误。我不明白为什么:sizeof(* A.dat_ptr)与sizeof(array)相同。因此,在最坏的情况下,我应该在某个地方得到胡言乱语,而不是在任务线上,对吗?
答案 0 :(得分:3)
您需要从函数返回array_info
结构(修改后)或(通常)将指向array_info
结构的指针传递给函数,以便您所做的更改会影响值在调用函数中。
typedef struct
{
int height;
int width;
int bottom;
unsigned int **dat_ptr; // Double pointer, not triple pointer
} array_info;
void create_array(array_info *A)
{
unsigned int **array = malloc(sizeof(*array) * A->height);
for (int i = 0; i < A->height; ++i)
array[i] = malloc(sizeof(**array) * A->width);
A->dat_ptr = array;
}
我假设您在某处检查了内存分配;但逻辑上是这个功能。从失败中恢复过程是繁琐的(但如果你要从函数返回而不是退出程序,则是必要的。)
void create_array(array_info *A)
{
unsigned int **array = malloc(sizeof(*array) * A->height);
if (array != 0)
{
for (int i = 0; i < A->height; ++i)
{
if ((array[i] = malloc(sizeof(**array) * A->width)) == 0)
{
for (int j = 0; j < i; j++)
free(array[j]);
free(array);
array = 0;
break;
}
}
}
A->dat_ptr = array;
}
如果dat_ptr
成员从create_array()
返回时为null,则调用函数知道函数失败。提供成功/失败返回值可能更好。
我正在使用C99,因此调用代码可能是:
array_info array = { .height = 10, .width = 20, .dat_ptr = 0 };
create_array(&array);
if (array->dat_ptr == 0)
...error handling...
请注意create_array()
中的代码可能需要检查空指针,负宽度或零宽度或高度。我不清楚bottom
元素应该包含什么,所以我把它保留为未初始化,这给了我一半的借口来使用指定的初始化器。您也可以非常清楚地编写初始化程序,而无需使用指定的初始化程序。