对二维数组的“memset”的混淆和“free”的错误
Posted
技术标签:
【中文标题】对二维数组的“memset”的混淆和“free”的错误【英文标题】:Confusion on `memset` of a 2D array and error on `free` 【发布时间】:2018-06-05 19:24:02 【问题描述】:我使用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
是一个二维指针或数组,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
。我对吗?如果不连续,怎么初始化成功呢? (来自测试过的开源代码)
【问题讨论】:
你必须遍历数组到free
它的指针元素,就像你对malloc
它们所做的那样。那么free(a);
数组不连续,不是真正的二维数组,还不如是jagged array。
如果多次调用malloc
,则不是连续内存。
你拥有的不是二维数组,而是数组数组。它们不占用一块连续的内存,因此您不能使用单个 memset
调用来设置整个内容。您将不得不循环到memset
和free
等,就像您对malloc
内存所做的那样。或者,您可以 malloc
使用单数调用将其全部连续,并使用算术计算行和列。
如果您使用0
作为memset
的数据,那么您可以使用calloc
而不是malloc
(尽管free
的问题是相同的。
@Weather Vane 如果像这样迭代地释放: for (in1=0;in1上图显示的是连续内存。
不,它没有。它显示了两个连续内存区域: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”的错误的主要内容,如果未能解决你的问题,请参考以下文章