这个问题是Malloc调用崩溃的延续,但在其他地方有效
我尝试了以下程序,我发现它工作(即没有崩溃 - 这也在上面提到的链接中提到).我很幸运能让它工作但是我正在寻找SO专家对于它为什么有效的合理解释?!
这里有一些关于memory
使用malloc()
wrt structures
和.的分配的基本理解pointers
malloc(sizeof(struct a) * n)
分配n
类型struct a
元素的数量.并且,可以使用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"
.并且,可以使用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;
}
Run Code Online (Sandbox Code Playgroud)
代码段如下:
#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;
}
Run Code Online (Sandbox Code Playgroud)
编辑:好的,如果我错误地执行以下操作
data * array = NULL;
if ((array = (data *)malloc(sizeof(data *) * n)) == NULL) {
Run Code Online (Sandbox Code Playgroud)
有没有办法捕获(在使用任何GCC
标志的编译时)这些无意识的编程错字,这些错误可能有时会起作用,并且可能随时爆发!我使用编译了这个-Wall
,没有发现任何警告!
没有.
sizeof(struct a*)
是指针的大小.
sizeof(struct a)
是整个结构的大小.
似乎存在一个根本性的误解.
malloc(sizeof(struct a)*n)分配n个类型struct a元素.
不,这就是人们通常在这样的电话之后使用它的原因.malloc(size)
分配一个size
字节的内存区域.你对该地区的所作所为完全取决于你.唯一重要的是你不要超越分配内存的限制.假设4字节float
和int
8字节double
,成功后malloc(100*sizeof(float));
,您可以使用400字节中的前120个作为15 double
秒的数组,接下来的120作为30 float
秒的数组,然后在其char
后面放置一个20 秒的数组int
如果您愿意,可以用35 秒填充剩余的140个字节.这是完全无害的定义行为.
malloc
返回一个void*
,可以隐式地转换为任何类型的指针,所以
some_type **array = malloc(100 * sizeof(data *)); // intentionally unrelated types
Run Code Online (Sandbox Code Playgroud)
非常好,它可能不是你想要的记忆量.在这种情况下很可能是因为指针往往具有相同的大小,而不管它们指向的是什么.
更容易给你错误的内存量
data *array = malloc(n * sizeof(data*));
Run Code Online (Sandbox Code Playgroud)
就像你拥有它一样.如果使用分配的内存作为n
类型元素的数组data
,则有三种可能性
sizeof(data) < sizeof(data*)
.那你唯一的问题是你在浪费一些空间.sizeof(data) == sizeof(data*)
.一切都很好,没有浪费空间,好像你根本没有打字错误.sizeof(data) > sizeof(data*)
.然后,您将访问在触摸稍后的数组元素时不应访问的内存,这是未定义的行为.根据各种各样的事情,可以始终如一地工作,好像你的代码是正确的,立即崩溃与segfault或其间的任何东西(从技术上讲,它可能以一种不能有意义地置于这两者之间的方式运行,但这将是不寻常的).如果你有意这样做,知道点1或2.适用,这是不好的做法,但不是错误.如果你无意中这样做,那么无论哪个点适用都是错误的,无害但很难找到,而1.或2.适用,有害但通常在3的情况下更容易检测.
在你的例子中.data
是4分.8个字节(可能),在64位系统上将它们放入1. resp.2.概率很高,在32位系统上分为2分.3.
避免此类错误的推荐方法是
type *pointer = malloc(num_elems * sizeof(*pointer));
Run Code Online (Sandbox Code Playgroud)