正确使用 memset 与动态分配的多维数组

Posted

技术标签:

【中文标题】正确使用 memset 与动态分配的多维数组【英文标题】:Proper use of memset with dynamically allocated multidimensional arrays 【发布时间】:2014-10-30 01:13:21 【问题描述】:

在循环的每次迭代中,我希望将动态定义的多维数组中的所有元素归零。

void my_function(int window_size, int row_size)

        double **window_arr;
        window_arr = (double **)calloc((window_size * 2), sizeof(double*));
            for (i = 0; i < (window_size * 2); ++i)
                window_arr[i] = (double*)calloc(3, sizeof(double));
            
        for (i = 0; i < row_size; ++i)
           ...
           memset(window_arr, 0, sizeof(window_arr) * (window_size * 2) * 3);
        
    

此段错误。在第一个memset之前设置断点,但是分配之后,看起来不错。

(gdb) p window_arr[1]
$1 = (double *) 0x22604f50
(gdb) p window_arr[1][0]
$2 = 0
(gdb) q

memset之后的断点

(gdb) p snp_window_arr[1]
$1 = (double *) 0x0
(gdb) p window_arr[1][0]
Cannot access memory at address 0x0
(gdb) q

我已经弄清楚如何将 memset 用于一维数组;我很想学习如何在上述场景中使用 memset。

【问题讨论】:

你能在第二个 calloc 之后(循环内)立即调用 memset 吗? 另外,我真的无法理解您对 memset 的使用。它的第三个参数不应该是这样的: sizeof(double) * (window_size * 2) * 3 您还假设二维数组是连续的,我不确定是否可以保证(可能)。如果没有,我的第一个建议是最安全的——分别 memset 每一行。 它不能通过将内存归零(callocmemset)来移植到零浮点变量。您应该遍历这些条目并将它们单独设置为0.0。 (但是为什么在使用 calloc 之后还要使用 memset?calloc 已经将它返回的内存归零了。) @ooga,因为循环的每次迭代都使用数组进行一些计算,然后需要将其归零。 【参考方案1】:

您正在构建一个指向数组的指针数组,而不是单个二维数组。这意味着您有一个指针数组,每个指针都指向一个一维数组。然后你尝试memset()整个2D空间,但这是不可能的,因为它不是连续分配的。

您应该考虑一次为所有元素分配一个带有空间的数组,因为您的逻辑二维数组无论如何都是矩形的。只需这样做:

double *window_arr = calloc((window_size * 2) * 3, sizeof(double));

然后:

memset(window_arr, 0, (window_size * 2) * 3);

当然,您随后会将该二维数组索引为window_arr[x*window_size*2 + y] 或类似名称,而不是window_arr[x][y]

【讨论】:

以上是关于正确使用 memset 与动态分配的多维数组的主要内容,如果未能解决你的问题,请参考以下文章

正确分配多维数组

“动态分配的内存模拟多维数组”的正确术语?

在 C++ 中将 memset 与多维数组一起使用

多维数组动态内存分配背后的算法是啥?

如何为多维数组动态分配内存

如何分配动态静态多维数组