二维数组 `memset` 上的困惑和 `free` 上的错误

标签 c free memset

我使用malloc动态分配内存,使用memset初始化二维数组,并使用free释放内存。代码是:

int n1=2,n2=5;
int in1;
float **a;
a = (float **)malloc(n1*sizeof(float *));
for (in1=0;in1<n1;in1++)
    a[in1] = (float *)malloc(n2*sizeof(float));
memset(a[0],0,n1*n2*sizeof(float));
free(*a);free(a);

运行代码时的第一个问题是: * `./try1' 中的错误:free():下一个尺寸无效(快速):0x0000000000c06030 *

第二个问题是:因为使用memset的前提是要有连续的内存。这就是它不适用于 3D 数组的原因(请参阅 Error in memset() a 3D array )。但这里a是一个2D指针或者数组,memset的输入是a[0]。我的理解是:

  +---------+---------+-----+--------------+
  | a[0][0] | a[0][1] | ... | a[0][n2 - 1] |
  +---------+---------+-----+--------------+
    ^
    |
 +------+------+-----+-----------+
 | a[0] | a[1] | ... | a[n1 - 1] |
 +------+------+-----+-----------+
           |
           v
         +---------+---------+-----+--------------+
         | a[1][0] | a[1][1] | ... | a[1][n2 - 1] |
         +---------+---------+-----+--------------+

上图显示的是连续内存。所以memset(a[0],0,n1*n2*sizeof(float));可以成功初始化**a。我对吗?如果不连续的话初始化怎么能成功呢? (来自经过测试的开源代码)

最佳答案

The above figure shows the contiguous memory.

不,没有。它显示了两个连续内存区域:a[0][0] -> a[0][n2 - 1] 和 a[1][0] -> a[1][n2 - 1]。

您可以尝试初始化并删除它们:

int n1 = 2, n2 = 5;
int in1;
float **a;
a = (float **)malloc(n1*sizeof(float *));
for (in1 = 0; in1<n1; in1++)
{ 
    a[in1] = (float *)malloc(n2*sizeof(float));
    memset(a[in1], 0, n2*sizeof(float));
}
for (in1 = 0; in1<n1; in1++)
{
    free(*(a+in1));
}
free(a);

仅在“真实”二维数组的情况下,例如 float a[2][5];,您对连续内存的假设是正确的。

关于二维数组 `memset` 上的困惑和 `free` 上的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50707543/

相关文章:

c++ - 在 C/C++ 中,是否保证 volatile 变量在线程之间具有最终一致的语义?

C 代码在 archlinux 上运行,但不能在 ubuntu 10.04 上运行

c - free() 在动态分配的内存中的作用域是什么?

C malloc错误释放结构

c - MAC地址在C代码中的表示

c - 在具有较大值(value)的Visual Studio中重新分配失败

c - 内部有其他结构数组的结构的可用内存 - C

c++ - 将 memset 从 C 替换/移植到 C++

c - 在c中为矩阵分配内存的问题

c - Memset 未将 char 指针归零