结构体指针,内存分配问题请教

weidu23 2019-01-29 09:46:17

首先声明,我采用的是Mac的Xcode软件编写的测试例代码,使用的是LLVM编译器,C99标准。

问题描述:malloc( sizeof( 结构体 ) ) 与 malloc( sizeof( 结构体指针 ) ) 有什么区别 ?

具体说明:
假定一个结构体


struct Stu{
int i ;
float f ;
double d ;
int * ip ;
float * fp ;
double *dp
}
定义2个变量 :
struct Stu *strup_1 = malloc(sizeof(struct Stu)) ;
struct Stu *strup_2 = malloc(sizeof(struct Stu*)) ;
打印1:sizeof(struct Stu) ; sizeof(struct Stu*) ;
打印2:sizeof(strup_1) ; sizeof(strup_2) ;

结果:
打印1的结果:40、8
打印2的结果:8 、8



问题具体:
问题1:请问,为什么struct Stu结构体的大小最大,有40,但是结构体指针的只有8 ? 只是因为 结构体指针是指针,指针大小都一样 ?
问题2:定义了2个变量,这两个变量已经malloc了,也就是说,已经开辟了内存大小,为什么还是指针的大小8 ,而不是实际开辟的大小?
问题3:定义的2个变量,一个是 malloc 结构体,一个是malloc 结构体指针,为什么打印出来的大小都一样,而且都是8,这是指针大小啊,不是实际开辟大小啊,怎么回事 ???
问题4:结构体指针分配内存,到底应该 malloc ( sizeof ( 结构体 ) ) , 还是 malloc ( sizeof ( 结构体指针 ) ) ???

在这请教了,各位 。

...全文
429 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
路见明非 2020-04-04
  • 打赏
  • 举报
回复
我想回复一下Randolf_A,sizeof(strup_1)=8,说明系统不是64位的吗????
Randolf_A 2020-02-22
  • 打赏
  • 举报
回复
题主,这个问题需要考虑到内存对齐。 内存对齐有几条规则,以你定义的结构体为例,第一个元素的内存偏移从零开始: 1.变量的内存偏移是变量实际占用内存的整数倍; 2.占用的总内存需要是最大元素大小的整数倍; 实际来看,你的系统应该是32bits: 1.int类型,实际大小 4 字节,内存占用 0-3; 2.float类型,实际大小 8 字节,内存占用 8-15,规则1 3. double类型,实际大小 8 字节,内存占用16-23; 4.指针,32位系统下实际大小 4 字节,内存占用24-27; 5.指针,4字节,内存占用28-31; 6.指针,4字节,内存占用32-35; 实际来看,共计 36 字节,规则2指出,内存占用应该是8的倍数,故sizeof()输出的结果是40
  • 打赏
  • 举报
回复
给你解释一下啊,指针和给指着开辟空间的关系,,指针呢他就是一个固定大小的变量,他这个变量呢存放的就是一个地址(这跟int i 中i存放一个int值是一个道理的),所以记住这句话指针就不难:指针就是个变量,存放的就是一个地址值,,然后地址知道了,你需要知道这个地址里面放的啥,这就好像开发楼盘,我知道在这个楼在5号大街,所以你知道去这个找这个楼,但这个地方还没建起来呢,所以他没有这个楼的。你只是知道,应该有。。这就跟你开辟空间是一个道理,你知道了楼的地址,然后你需要盖楼,楼的大小是100,你就malloc(100)的,如果小了,那就完了。这就好像你malloc(sizeof(struct Stu*)),你只是把门牌号的大小分配出来了。但盖楼的大小需要的是sizeof(Struct Stu),那你的楼就完蛋了。这里楼的大小就是sizeof(struct Stu)40, 楼地址的大小就是sizeof(struct stu*)也就是8,那结果可想而知,你在8大小的地方要存放40大小的楼,,,这个sizeof就是个运算符,运算符!!!他就能得出个size_t(这里你就理解成int值)的结果。也就是说,如果你能保证你的值没错而且以后不更改,那malloc(40)自己往里塞值就行了,,除非你指针用的特别好,否则不要这么做,还是sizeof吧。然后还有一点,指针这个东西是不需要分配空间的,也就是说你需要给楼分配空间,但不需要给楼的地址分配,这个解释起来比较深奥,涉及到堆栈的知识,新手就先别探讨了,总之门牌号不需要分配大小。。malloc(sizeof(struct stu*))这种情况除非特殊高手用来计算,否则是不会有的。再说说你的那个类似等式的东西,等号前面就是楼的地址,等号后面就是实际的楼,懂了吧。你可以根据楼的地址找到楼,但楼这个实体有没有,还得取决于你盖没盖,还是那句话,除非你是指针高手,就sizeof(类型)就完事了,如果是数组就sizeof(类型)* 数组的数量
weidu23 2019-01-30
  • 打赏
  • 举报
回复
引用 6 楼 niiiloc 的回复:
你的所有问题实质是对malloc理解不深刻导致 malloc的入参是申请内存的大小,出参是申请出来内存的位置,两者不要搞混了
谢谢,也就是说,要用 malloc ( sizeof( 结构体 ) ) , 这样就申请了结构体大小的内存,然后= ,表示指针指向了这块
自信男孩 2019-01-29
  • 打赏
  • 举报
回复
首先需要了解sizeof的原理,sizeof返回类型的长度(占用内存的字节数),sizeof结构体类型,得到的是类型的大小。sizeof结构体指针是指针类型的大小,指针类型要根据系统的CPU位数,如果是32位系统,那么指针类型长度为4,若为64位系统,则是8.
zaley 2019-01-29
  • 打赏
  • 举报
回复
指针大小 永远 4字节(32位程序) 或8字节(64位程序) , 仅仅一个地址而已
耕者走兔 2019-01-29
  • 打赏
  • 举报
回复
如你所愿,编译器已经为你分配了你所请求的存储空间,你还有什么满意的尼。

为什么一个是 40 个字节,而另一个 8 字节? 那是因为,你请求的就那么多,编译器没有克扣你1个字节。
weidu23 2019-01-29
  • 打赏
  • 举报
回复
引用 1 楼 qq_40223493 的回复:
sizeof函数里是类型的大小。*p和p是不同类型,没有指向空间一说,第一个结构体类型名大小40没错,第二个结构体指针类型,三四都是结构体指针类型,编译器指针类型占用八个字节。
那么,接一下问题4,继续请教下: 结构体指针分配内存,到底应该 malloc ( sizeof ( 结构体 ) ) , 还是 malloc ( sizeof ( 结构体指针 ) ) ??? 比如, 我应该使用 struct Stu *p = malloc(sizeof(struct Stu)) ; 还是该使用 struct Stu *p = malloc(sizeof(struct Stu*)) ; 请教下
qq_40223493 2019-01-29
  • 打赏
  • 举报
回复
sizeof函数里是类型的大小。*p和p是不同类型,没有指向空间一说,第一个结构体类型名大小40没错,第二个结构体指针类型,三四都是结构体指针类型,编译器指针类型占用八个字节。
636f6c696e 2019-01-29
  • 打赏
  • 举报
回复
你的所有问题实质是对malloc理解不深刻导致 malloc的入参是申请内存的大小,出参是申请出来内存的位置,两者不要搞混了

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧