“malloc(sizeof(struct a *))”和“malloc(sizeof(struct a))”是否相同?

这个问题是Malloc调用崩溃的延续,但在其他地方有效

我尝试了以下程序,我发现它工作(即没有崩溃 – 这也在上面提到的链接中提到)。 我很幸运能让它工作但是我正在寻找SO专家对于它为何起作用的合理解释?!

以下是使用malloc() wrt structurespointers分配memory一些基本知识

  • malloc(sizeof(struct a) * n)分配n个类型struct a元素。 并且,可以使用pointer-to-type-"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" ,就是这样

  1. 有效将其分配给struct a *而不是struct a **
  2. 有效访问/取消引用已分配的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  #include  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编译了这个,发现没有警告!

似乎存在一个根本性的误解。

malloc(sizeof(struct a)* n)分配n个类型struct a元素。

不,这就是通常在这样的电话之后使用它的原因。 malloc(size)分配size bytes的内存区域。 你对该地区的所作所为完全取决于你。 唯一重要的是你不要超越分配内存的限制。 在成功的malloc(100*sizeof(float));之后假设有4个字节的floatint以及8个字节的double malloc(100*sizeof(float)); ,您可以使用400字节中的前120个作为15个double s的数组,接下来的120作为30个float的数组,然后在其后面放置一个20个char的数组,并用35填充剩余的140个字节如果你愿意的话。 这是完全无害的定义行为。

malloc返回一个void* ,它可以隐式地转换为任何类型的指针,所以

 some_type **array = malloc(100 * sizeof(data *)); // intentionally unrelated types 

非常好,它可能不是你想要的内存量。 在这种情况下很可能是因为指针往往具有相同的大小,而不管它们指向的是什么。

更有可能给你错误的内存量

 data *array = malloc(n * sizeof(data*)); 

就像你拥有它一样。 如果将分配的内存块用作n data类型元素的数组,则有三种可能性

  1. sizeof(data) < sizeof(data*) 。 那你唯一的问题是你在浪费一些空间。
  2. sizeof(data) == sizeof(data*) 。 一切都很好,没有浪费空间,好像你根本没有打字错误。
  3. sizeof(data) > sizeof(data*) 。 然后,您将访问在触摸稍后的数组元素时不应访问的内存,这是未定义的行为。 根据各种各样的事情,这可能始终像你的代码是正确的一样工作,立即崩溃与段错误或介于两者之间的任何东西(从技术上讲,它可能以不能有意义地置于这两者之间的方式运行,但这将是不寻常的)。

如果你有意这样做,知道点1或2.适用,这是不好的做法,但不是错误。 如果你无意中这样做,那么无论哪个点适用都是错误的,无害但很难找到1.或2.适用,有害但通常在3的情况下更容易检测。

在你的例子中。 data是4分。 8个字节(可能),在64位系统上将它们放入1. resp。 2.概率很高,在32位系统上变为2分。 3。

避免此类错误的推荐方法是

 type *pointer = malloc(num_elems * sizeof(*pointer)); 

没有。

sizeof(struct a*)指针的大小。
sizeof(struct a)是整个struct的大小。

这个array = (data *)malloc(sizeof(data *) * n)为struct data分配一个sizeof(data*)指针 ),如果你想这样做,你需要一个你的array作为data** array

在您的情况下,您希望指针指向sizeof(data) ,内存中的结构,而不是指向另一个指针。 这将需要data** (指针指针)。

将它赋给struct a *而不是struct a **是否有效?

好吧,从技术上讲,这样分配是有效的,但取消引用这样的指针是错误的(UB)。 你不想这样做。

有效访问/取消引用已分配的数组(n元素)-of-pointers-to-type-“struct a”使用指针到“struct a”?

不,未定义的行为。