2

我一直在为我的电磁仿真课程编写一段代码,但遇到了一个问题。我决定做一些额外的事情,将原始计算扩展到多达 10^8 个元素的非常大的网格,所以现在我必须使用 malloc()。

到目前为止,一切都很好,但是由于我更喜欢​​将代码保存在库中,然后使用编译器的 inline 选项进行编译,因此我需要一种在函数之间传递信息的方法。所以,我开始使用结构来跟踪网格的参数,以及指向信息数组的指针。我通过以下方式定义了结构:

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;

其中指向无符号整数的三重指针是指向二维数组的指针。我必须这样做,否则它是按值传递的,我无法从函数内更改它。

现在,当我尝试使用以下函数为结构分配内存时:

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) 相同。因此,在最坏的情况下,我应该在某个地方出现胡言乱语,而不是在分配行中,对吧?

4

1 回答 1

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()。提供成功/失败返回值可能会更好。

我使用的是 C99,所以调用代码可能是:

array_info array = { .height = 10, .width = 20, .dat_ptr = 0 };
create_array(&array);
if (array->dat_ptr == 0)
    ...error handling...

请注意,其中的代码create_array()可能需要检查空指针、负数或零宽度或高度。我不清楚bottom元素应该包含什么,所以我没有初始化它,这给了我使用指定初始化程序的一半借口。您也可以非常清楚地编写初始化程序,而无需使用指定的初始化程序。

于 2012-11-04T23:44:08.493 回答