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

时间:2012-01-06 18:01:30

标签: c pointers struct

这个问题是Malloc call crashing, but works elsewhere

的延续

我尝试了以下程序,我发现它正常工作(即没有崩溃 - 这也在上面提到的链接中提到过)。我很幸运能让它运转起来,但我正在寻找SO专家为何这样做有效的解释?!

以下是使用memory w.r.t malloc()structures

分配pointers的一些基本知识
  • malloc(sizeof(struct a) * n)分配nstruct a个元素。并且,可以使用pointer-to-type-"struct a"存储和访问此内存位置。基本上是struct a *
  • malloc(sizeof(struct a *) * n)分配nstruct 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"
  3. 访问/取消引用已分配的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编译了这个,没有发现任何警告!

4 个答案:

答案 0 :(得分:7)

没有

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

答案 1 :(得分:5)

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

  

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

不,这就是通常在通话后使用它的原因。 malloc(size)分配size字节的内存区域。你对该地区的所作所为完全取决于你。唯一重要的是你不要超越分配内存的限制。假设4字节floatint以及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元素的数组,则有三种可能性

  1. data。那么你唯一的问题是你在浪费一些空间。
  2. sizeof(data) < sizeof(data*)。一切都很好,没有浪费空间,好像你根本没有打字错误。
  3. 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”?

不,未定义的行为。