指向struct的指针

时间:2016-03-22 02:49:45

标签: c arrays pointers struct

我有以下代码

#include <stdlib.h>
#include <stdio.h>

typedef struct {
    int age;
} data;

int storage (data **str) {
    *str = malloc(4 * sizeof(**str));
    (*str)[0].age = 12;
    return 0;
}

int main() {
    data *variable = NULL;
    storage(&variable);
    return 0;
}

我是从网站上获取的。我认为我对指针概念的基本指针有误解,因为在这段代码中,我们有一个指向结构的指针,variable,我们将它传递给storage函数,它需要指向结构类型的指针。在内存被malloced后,我不明白这个任务

(*str)[0].age = 12

它的分配好像,str属于(*)[]类型。我不明白这个赋值是如何工作的,比如str现在是一个结构数组的指针?

4 个答案:

答案 0 :(得分:2)

可以这样说明

main:
 data* variable = NULL;   //variable is a pointer
 storage(&variable)       //the address of the pointer is &variable 

storage(data**)允许函数获取地址 指针variable

这允许storage更改variable指向

的内容

storage中,以下语句通过解除引用来更改variable指向的内容(因为我们确实传递了variable的地址):

*str = malloc(4 * sizeof(**str) )

malloc分配一个包含四个结构的内存块(每个结构的大小为sizeof(struct data)bytes)

结构只是一种访问内存部分的便捷方式 struct描述了内存的布局。声明

(*str)[0].age = 12;

相当于

data* d = *str; 
d[0].age = 12;

或者您可以将其写为带偏移量的ptr:

data* d = *str;
*(d + 0).age = 12;

编辑:关于malloc的澄清

malloc返回以字节为单位分配的内存块,返回类型mallocvoid*,因此根据定义,它没有类型,可以分配给任意类型的指针:

T* ptr = malloc(n * sizeof(T));

在分配给ptr之后,通过使用指针T *将内存视为T类型的一个或多个元素

答案 1 :(得分:2)

首先,关于解除引用指针的C语法的注释:

a[b]相当于*(a + b),相当于*(b + a),相当于b[a]

现在,在

int main() {
    data *variable = NULL;
    storage(&variable);
    return 0;
}

variable的类型为&#34;指向data&#34;的指针,因此其地址&variable的类型为&#34;指向{{1}的指针}&#34 ;.这将传递给data,并且是参数int storage(data **str)的正确类型。

str

此处,int storage (data **str) { *str = malloc(4 * sizeof(**str)); (*str)[0].age = 12; return 0; } 被解除引用,产生类型str的左值,指定与data * s main()相同的对象。由于它是左值,因此可以将其分配给。

variable分配没有声明类型的内存,足够大(并且足够对齐)以包含四个malloc()类型的连续对象。它返回指向分配开头的指针。

data现在是一个左值,指定类型为(*str)[0]的对象,并通过访问通过此表达式分配的内存data有效类型记忆变为malloc()data将值(*str)[0].age = 12;分配给此对象的12 - 成员,使结构的其他成员(以及分配的内存的其余部分)保持未初始化状态。

答案 2 :(得分:0)

嗯,我认为你的代码完全相同:

#include <stdlib.h>
#include <stdio.h>

typedef struct
{
    int age;
} data;

int main()
{
    data *variable = NULL;
    variable = malloc(4 * sizeof(*variable));
    *(variable + 0).age = 12;
    return 0;
}

所以variable使用一块内存进行了操作,该内存块足够容纳4 data s(从variable[0]variable[3])。就是这样。

答案 3 :(得分:0)

这段代码可能有助于说明发生了什么,真正有趣的一行是

assert(sizeof(**str2) == sizeof(data));

你的数字可能因我的不同而有所不同,但首先让我们为测试目的创建一个相当枯燥但难以伪造的结构。

#include <assert.h>
#include <stdlib.h>
#include <stdio.h>

typedef struct {
  uint8_t  age;
  uint8_t  here_as_illustartion_only[1728];
} data;

int main() {
    data    str; 
    data *  str1 = &str;  
    data ** str2 = &str1;  
    printf("sizeof(str)    =%*zu\n", 5, sizeof(str));
    printf("sizeof(str1)   =%*zu\n", 5, sizeof(str1));
    printf("sizeof(str2)   =%*zu\n", 5, sizeof(str2));
    printf("sizeof(*str2)  =%*zu\n", 5, sizeof(*str2));
    printf("sizeof(**str2) =%*zu\n", 5, sizeof(**str2));

    assert(sizeof(**str2) == sizeof(data));
    return 0;
}

在我的机器上打印以下内容

sizeof(str)    = 1729
sizeof(str1)   =    8
sizeof(str2)   =    8
sizeof(*str2)  =    8
sizeof(**str2) = 1729

注意指向指针的大小,即 sizeof(**)是我们正在寻找的枯燥数字。