定义一个结构体指针需要分配存储空间?

 

 

前言

问题的来源于在学数据结构的时候,C++的语法和C语言的语法竟然不一样。

1.首先函数的参数有两种传递方式,一个是值传递,一个是地址传递。当指针作为参数传递的时候,即为地址传递,但C++写的时候需要加&引用符号,而C语言却不用。

2.本文谈的是这个问题,即为当声明一个结构体指针时,为什么还有new(C++)或者malloc()这种语句,一直搞不清楚,后台问bb,然后百度了一下,才明白

正文

看到一篇文章是这么写的
问题描述:
主题:定义结构体指针时,有没有同时分配存储空间
定义结构体指针时,有没有同时分配存储空间啊?
看到结构体的数组定义好以后就直接可以用了。
但是结构体指针在链表中还要malloc()申请空间。
这是为什么啊?
1楼
定义结构体指针时并没有分配存储空间,所以要用malloc()申请空间。
2楼
很明显,你还没有搞清楚什么是指针,至于结构体变量和结构体指针,更是很混淆,所以这里不是因为数组的问题。
举个例子:
 
//下面仅仅是定义一个类型,不会产生变量,所以不存在分配空间的问题
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; //okdats2[0]->i = 20; //ok
}

 

3楼
声明任何对象并定义变量,包括指针都会开辟空间,除了静态成员在一个特别的区,其他的在栈上开辟空间,不用了自动清理,用malloc, realloc, calloc, new new[]开辟空间是动态分配空间,在堆上进行。值得说明的是,栈空间很小(相对于堆而言),很"昂贵",但是通常执行更快。


在Windows下,一个进程的栈在最高端,向下增长,堆在栈下面,向栈的方向增长,下面是数据和代码。Linux下内存布局由开发工具和操作系统合作负责,这四个部分相对位置布局不确定。


Windows下一个进程的线性地址空间布局:


--------------------
                   |
                   |
栈                 V
                   V
                   V
--------------------
                   ^
                   ^
堆                 |
                   |
                   |
--------------------


其他
4楼
windows默认栈大小是1M
栈和堆是共享一内存的,可以调节它们的比例。来设置栈和堆的大小。
不过一般情况下,还是用不着的。。
5楼
[quote]
有人告诉我:
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 本质上并没有什么不同,只是一个变量是栈上,一个是堆上,都是一个地址赋值。

所以,所谓的分配空间,就是对指针赋值,把一个变量的地址赋值给一个指针。
----------我是萌萌哒分割线----------
很明显三楼和四楼讲的有点底层了,不过其他楼层说的很明白,首先只是分配了指针本身的存储空间,指针指针还没有被赋值,通过new或者malloc()语句是为了给结构体变量分配内存空间,即为指针赋值,即指针指向的内容的信息,便有了指针指向的数据内容和空间。
----------我是萌萌哒分割线---------- 
原文地址:http://bbs.pfan.cn/post-284115.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/510147.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

内核模式和用户模式

2位x86系统,每个进程的空间是4GB,即地址0x00000000到0xFFFFFFFF。 为了高效调用,Windows会把操作系统的内核数据和代码映射的系统中所有进程的进程空间中。因此4GB空间被划分为两个区域:用户空间和系统空间,默认大小为…

HUE 提交Schedule 时区问题

1.配置如下,每天定时 14:02 启动 2.运行后,任务状态提示,时间变成了06:02:00 3.修改HUE的时区配置 修改后 3.重启 4.然后执行发现,还是不起作用,后排查了一下oozie问题,发现hue的时区配置对oozie无法生效…

高斯日记

大数学家高斯有个好习惯:无论如何都要记日记。 他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210 后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几…

线程同步之条件变量

一、引言 假设有一个任务,由我和张三共同完成。张三把寄来的文稿初步审阅后放入一个队列,我负责将这个队列中的文稿进行审批,决定刊登与否。张三审阅一份文稿需要15分钟,我处理一个文稿需要2分钟。 如果将张三和我看作两个线程&am…

cuda的global memory介绍

CUDA Memory Model 对于程序员来说,memory可以分为下面两类: Programmable:我们可以灵活操作的部分。Non-programmable:不能操作,由一套自动机制来达到很好的性能。 在CPU的存储结构中,L1和L2 cache都是n…

串口通信参数

串口是一种非常通用的设备通信的协议(不要与通用串行总线Universal Serial Bus(USB)混淆)。大多数计算机包含两个基于RS232的串口。串口同时也是仪器仪表设备通用的通信协议;很多GPIB兼容的设备也带有RS-232口。同时,串口通信协议…

马虎的算式

小明是个急性子,上小学的时候经常把老师写在黑板上的题目抄错了。 有一次,老师出的题目是:36 x 495 ? 他却给抄成了:396 x 45 ? 但结果却很戏剧性,他的答案竟然是对的!! 因为 36 * 495 …

identifier __ldg is undefined

__ ldg() 内置仅适用于计算能力3.5(或更高版本)架构。 这意味着: 必须在计算3.5(或更新版本)GPU上运行必须针对计算3.5(或更新版本)的GPU进行编译不能为旧体系结构编译。…

Mybase到期 破解

1.找到mybase安装目录 C:\Users\Zsh\AppData\Local\wjjsoft\nyfedit6 2.打开nyfedit.ini 3. 内容中查找 App.UserLic.FirstUseOn 删除 4.保存打开mybase即可

Android中给按钮同时设置背景和圆角示例代码

前言 最近在做按钮的时候遇到在给按钮设置一张图片作为背景的同时还要自己定义圆角,最简单的做法就是直接切张圆角图作为按钮就可以了,但是如果不这样该怎么办呢,看代码: 下面来看效果图 一、先建一个圆角的shape文件:…

awk使用方法

awk是行处理器: 相比较屏幕处理的优点,在处理庞大文件时不会出现内存溢出或是处理缓慢的问题,通常用来格式化文本信息 awk处理过程: 依次对每一行进行处理,然后输出 awk命令形式: awk [-F|-f|-v] ‘BEGIN{} //{command1; command2} END{}’…

cude的__ldg使用

一般使用__ldg是更好的选择。通过constant缓存存储的数据必须相对较小而且必须获取同一个地址以便获取最佳性能,相反,只读缓存则可以存放较大的数据,且不必地址一致。 __global__ void transpose2(const real* A, real* B, const int N) {co…

html中contentEditable属性

contentEditable的主要功能是允许用户在线编辑元素中的内容&#xff0c;contentEditable是一个布尔型属性&#xff0c;因此在使用时候赋予初值&#xff0c;默认由inherit状态确定(看其父元素状态) 示例代码&#xff1a; <!doctype html> <html> <head> <…

Storm tick 功能

1. tick的功能 Apache Storm中内置了一种定时机制——tick&#xff0c;它能够让任何bolt的所有task每隔一段时间&#xff08;精确到秒级&#xff0c;用户可以自定义&#xff09;收到一个来自__systemd的__tick stream的tick tuple&#xff0c;bolt收到这样的tuple后可以根据业…

cuda的shared momery

CUDA SHARED MEMORY 在global Memory部分&#xff0c;数据对齐和连续是很重要的话题&#xff0c;当使用L1的时候&#xff0c;对齐问题可以忽略&#xff0c;但是非连续的获取内存依然会降低性能。依赖于算法本质&#xff0c;某些情况下&#xff0c;非连续访问是不可避免的。使用…

图的表示方法和C++实现

图的表示最长用的两种方法是&#xff1a; 1&#xff09;、邻接矩阵表示法 2&#xff09;、邻接表表示 下面是两种构造图的方法 1&#xff09;邻接矩阵&#xff1a; [cpp] view plaincopy#include <iostream> #include <vector> using namespace std; //枚…

html中contextmenu属性

contexmenu属性用于定义<div>元素的上下文菜单&#xff0c;所谓上下文菜单就是用书右键点击元素时候出现。 示例代码&#xff1a; <!doctype html> <html> <head> <meta charset"utf-8"> <title> </title> </head>…

Hive 分区表操作 创建、删除

删除某个分区指定数据 ALTER TABLE tableName DROP PARTITION (times 201851); ALTER TABLE user_portrait_task DROP PARTITION (times > 201801);

成为专业程序员的 6 个技巧

1.在你责怪别人之前&#xff0c;先检查自己的代码 先想一想自己的假设和其他人的假设。来自不同供应商的工具可能内置不同的假设&#xff0c;即便是相同的供应商对于不同的工具&#xff0c;其假设也可能不同。 当其他人正在报告一个你不能重复的问题的时候&#xff0c;去看看他…

HUE集成Hbase

目录 一、Hbase开启代理用户相关配置 二、代理用户授权认证 三、检查HUE在hue.ini文件中指定的HBASE的本地配置目录 一、Hbase开启代理用户相关配置 Cloudera Manager修改Hbase配置或Hbase配置文件-hbase-site.xml <property><name>hbase.thrift.support.proxyu…