C\C++中结构体变量与结构体指针内存分配问题

声明一个结构体变量,无论是否初始化,都开辟内存,声明一个结构体指针变量,对其初始化的时候才会开辟内存。

A a[3];  a是A型的,有3个,当然分配A乘3大小的空间

A* a;    a是A*型的,当然只分配A*大小的空间,而不会分配A大小的空间

好像跟你说的不太一样,结构体数组的话,我在课本里看到的确不用再次申请空间了啊[/quote]

结构体变量分配结构体本身大小的空间,结构体指针分配4个字节,其实任何类型的指针都是分配四个字节的指针空间。
所以:
A a[3]; //a里面是三个A变量,所以分配三个结构体大小
A *a;  //a是一个指针,分配4个字节,就算A再大,a也只是4个字节,因为任何类型的指针都是4个字节。要使用a,必须先要对指针初始化,也即分配空间了。
如:
A *a;
a = (A*)malloc(sizeof(A));

我们完全可以撇开结构体,把问题简单化成int类型来说明这个指针问题:
int a1[10];
int *a2;

很容易知道,a1是包含10个int的数组,大小也就是10*sizeof(int)。我们可以直接使用a1不要在进行什么初始化或者分配空间的游戏,因为数组a1里面本身存放的就是int变量本身了。

然后a2,是一个int*的东西,也就是整型指针,a2不能存放int变量,它只能存放地址,一个int变量的地址。如果要使用a2,必须首先对a2初始化,即将它指向一个int变量的地址,如:
a2 = (int*)malloc(sizeof(int));
或者
int i = 10;
a2 = &i;
所以,malloc函数的作用是首先声明一个变量,然后返回该变量的地址。
所以:a2 = (int*)malloc(sizeof(int)) 的含义就是把该变量的地址赋值给a2,和a = &i 本质上并没有什么不同,只是一个变量是栈上,一个是堆上,都是一个地址赋值。

所以,所谓的分配空间,就是对指针赋值,把一个变量的地址赋值给一个指针。

定义结构体指针,内存空间分配问题

//下面仅仅是定义一个类型,不会产生变量,所以不存在分配空间的问题
struct data
{
    int i;
    int j;
};

void main(void)
{
    struct data dat1; //定义一个struct data类型的变量,和int i同理。
    printf("%d\n", sizeof(struct data)); //8个字节
    printf("%d\n", sizeof(dat1));        //8个字节

    struct data* pdat1;//定义一个struct data类型的指针,和int *pi 同理。
    printf("%d\n", sizeof(pdat1));        //4个字节,就是一个指针的空间,pdat1并没有结构体变量的信息。

    pdat1 = (struct data*)malloc(sizeof(struct data)); //申请一个空间,把该空间地址给pdat1.
    printf("%d\n", sizeof(*pdat1));      //8个字节

    struct data dats1[2]; 
    printf("%d\n", sizeof(dats1));     //16个字节,两个data变量,不是data指针。
    dats1[0].i = 20;  //可以直接使用数组里面的结构体变量
    dats1[0].j = 30;
    
    struct data* dats2[2]; //指针数组,包含两个指针,而不是结构体变量
    printf("%d\n", sizeof(dats2));  //8个字节,两个指针的大小
    dats2[0]->i = 20; //错误!还没有给dats2[0] 指针分配空间
    dats2[0]->i = 20; //错误!还没有给dats2[0] 指针分配空间
    dats2[0] = (struct data*)malloc(sizeof(struct data)); //分配空间
    dats2[0]->i = 20; //ok
    dats2[0]->i = 20; //ok

}

猜你喜欢

转载自blog.csdn.net/qfc8930858/article/details/81154081