这个问题是Malloc call crashing, but works elsewhere
的延续我尝试了以下程序,我发现它正常工作(即没有崩溃 - 这也在上面提到的链接中提到过)。我很幸运能让它运转起来,但我正在寻找SO专家为何这样做有效的解释?!
以下是使用memory
w.r.t malloc()
和structures
pointers
的一些基本知识
malloc(sizeof(struct a) * n)
分配n
个struct a
个元素。并且,可以使用pointer-to-type-"struct a"
存储和访问此内存位置。基本上是struct a *
。malloc(sizeof(struct a *) * n)
分配n
个struct a *
个元素。然后,每个元素都可以指向struct a
类型的元素。基本上malloc(sizeof(struct a *) * n)
会分配array(n-elements)-of-pointers-to-type-"struct a"
。并且,可以使用pointer-to-(pointer-to-"struct a")
存储和访问分配的存储器位置。基本上是struct a **
。因此,当我们创建array(n-elements)-of-pointers-to-type-"struct a"
时,是
struct a *
而不是struct a **
?array(n-elements)-of-pointers-to-type-"struct a"
?pointer-to-"struct a"
醇>
data * array = NULL;
if ((array = (data *)malloc(sizeof(data *) * n)) == NULL) {
printf("unable to allocate memory \n");
return -1;
}
代码段如下:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
typedef struct {
int value1;
int value2;
}data;
int n = 1000;
int i;
int val=0;
data * array = NULL;
if ((array = (data *)malloc(sizeof(data *) * n)) == NULL) {
printf("unable to allocate memory \n");
return -1;
}
printf("allocation successful\n");
for (i=0 ; i<n ; i++) {
array[i].value1 = val++;
array[i].value2 = val++;
}
for (i=0 ; i<n ; i++) {
printf("%3d %3d %3d\n", i, array[i].value1, array[i].value2);
}
free(array);
printf("freeing successful\n");
return 0;
}
编辑: 好的,如果我通过 错误
执行以下操作data * array = NULL;
if ((array = (data *)malloc(sizeof(data *) * n)) == NULL) {
有没有办法捕获(在使用任何GCC
标志的编译时)这些无意识的编程错误,这些错误可能有时会起作用,并且可能随时爆发!我使用-Wall
编译了这个,没有发现任何警告!
答案 0 :(得分:7)
没有
sizeof(struct a*)
是指针的大小
sizeof(struct a)
是整个结构的大小。
答案 1 :(得分:5)
似乎存在一个根本性的误解。
malloc(sizeof(struct a)* n)分配n个类型struct a elements。
不,这就是通常在通话后使用它的原因。 malloc(size)
分配size
字节的内存区域。你对该地区的所作所为完全取决于你。唯一重要的是你不要超越分配内存的限制。假设4字节float
和int
以及8字节double
,在成功malloc(100*sizeof(float));
之后,您可以将400字节中的前120个用作15 {{1}的数组s,接下来的120作为30 double
s的数组,然后在其后面放置一个20 float
的数组,并用35 char
s填充剩余的140个字节你希望。这是完全无害的定义行为。
int
返回malloc
,可以隐式地转换为任何类型的指针,所以
void*
非常好,可能不是你想要的内存量。在这种情况下很可能是因为指针往往具有相同的大小,而不管它们指向的是什么。
更有可能给你错误的内存量
some_type **array = malloc(100 * sizeof(data *)); // intentionally unrelated types
就像你拥有它一样。如果您使用分配的内存作为data *array = malloc(n * sizeof(data*));
类型n
元素的数组,则有三种可能性
data
。那么你唯一的问题是你在浪费一些空间。sizeof(data) < sizeof(data*)
。一切都很好,没有浪费空间,好像你根本没有打字错误。sizeof(data) == sizeof(data*)
。然后,您将访问在触摸稍后的数组元素时不应访问的内存,这是未定义的行为。根据各种各样的事情,这可能始终像你的代码一样正常工作,立即崩溃与段错误或介于两者之间的任何东西(从技术上讲,它可能以不能有意义地置于这两者之间的方式运行,但这将是不寻常的。)< / LI>
醇>
如果你有意这样做,知道点1或2.适用,它是坏练习,但不是错误。如果你无意中这样做,那么无论哪个点适用都是错误的,无害但很难找到1.或2.适用,有害但通常在3的情况下更容易检测。
在你的例子中。 sizeof(data) > sizeof(data*)
是4分。 8个字节(可能),在64位系统上将它们放入1. resp。 2.概率很高,在32位系统上分为2分。 3。
避免此类错误的推荐方法是
data
答案 2 :(得分:1)
此array = (data *)malloc(sizeof(data *) * n)
为结构sizeof(data*)
分配data
(指针),如果您想这样做,则需要array
data** array
成为sizeof(data)
。
在您的情况下,您希望指针指向data**
,即内存中的结构,而不是指向另一个指针。这需要{{1}}(指向指针的指针)。
答案 3 :(得分:1)
将结果分配给struct a *而不是struct a **?
是否有效
嗯,从技术上讲,这样分配是有效的,但取消引用这样的指针是错误的(UB)。你不想这样做。
有效访问/取消引用已分配的数组(n元素)-of-pointers-to-type-“struct a”使用指针到“struct a”?
不,未定义的行为。