定义一个结构体指针需要分配存储空间?
生活随笔
收集整理的這篇文章主要介紹了
定义一个结构体指针需要分配存储空间?
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?
?
前言
問題的來源于在學數據結構的時候,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 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎
總結
以上是生活随笔為你收集整理的定义一个结构体指针需要分配存储空间?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MyBatis之Mapper动态代理开发
- 下一篇: VS2013常用快捷键设置