c - 在结构体中使用指向动态二维数组的指针

标签 c struct segmentation-fault malloc multidimensional-array

我一直在为电磁仿真类(class)编写一段代码,但遇到了问题。我决定做一些额外的事情,将原始计算扩展到最多 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) 相同。因此,在最坏的情况下,我应该在某处得到乱码,而不是在赋值行中,对吗?

最佳答案

您需要从函数返回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;
}

如果从 create_array() 返回时 dat_ptr 成员为 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 元素应包含什么,因此我将其保留为未初始化,这给了我使用指定初始值设定项的一半借口。您还可以非常清楚地编写初始化程序,而无需使用指定的初始化程序。

关于c - 在结构体中使用指向动态二维数组的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13224113/

相关文章:

c++ - 为什么这个指针不是 NULL,尽管它从未被初始化?

c++ - 为什么在遗留 strcpy() 中没有健全性检查

c - 带有填充的结构的补码校验和?

c++ - 在 SQLITE 数据库中写入记录需要花费大量时间。如何提高插入操作的效率?

c - 从堆栈结构 C 释放指针

c - 删除c中链表中最后一项的问题

c - ## 运算符我缺少什么

c - 6.5.2.3 结构和 union 成员中 C 中严格别名规则的异常(exception)

c - OpenMP 段错误

c - 我无法理解这个段错误