我有以下代码
#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
现在是一个结构数组的指针?
答案 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
返回以字节为单位分配的内存块,返回类型malloc
为void*
,因此根据定义,它没有类型,可以分配给任意类型的指针:
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(**)是我们正在寻找的枯燥数字。