电竞比分网-中国电竞赛事及体育赛事平台

分享

定義結(jié)構(gòu)體指針時(shí),有沒有同時(shí)分配存儲(chǔ)空間?

 玫瑰余香1030 2019-01-19

前言

問題的來(lái)源于在學(xué)數(shù)據(jù)結(jié)構(gòu)的時(shí)候,C++的語(yǔ)法和C語(yǔ)言的語(yǔ)法竟然不一樣。

1.首先函數(shù)的參數(shù)有兩種傳遞方式,一個(gè)是值傳遞,一個(gè)是地址傳遞。當(dāng)指針作為參數(shù)傳遞的時(shí)候,即為地址傳遞,但C++寫的時(shí)候需要加&引用符號(hào),而C語(yǔ)言卻不用。

2.本文談的是這個(gè)問題,即為當(dāng)聲明一個(gè)結(jié)構(gòu)體指針時(shí),為什么還有new(C++)或者malloc()這種語(yǔ)句,一直搞不清楚,后臺(tái)問bb,然后百度了一下,才明白

正文

看到一篇文章是這么寫的
問題描述:
主題:定義結(jié)構(gòu)體指針時(shí),有沒有同時(shí)分配存儲(chǔ)空間
定義結(jié)構(gòu)體指針時(shí),有沒有同時(shí)分配存儲(chǔ)空間啊?
看到結(jié)構(gòu)體的數(shù)組定義好以后就直接可以用了。
但是結(jié)構(gòu)體指針在鏈表中還要malloc()申請(qǐng)空間。
這是為什么?。?/span>
1樓
定義結(jié)構(gòu)體指針時(shí)并沒有分配存儲(chǔ)空間,所以要用malloc()申請(qǐng)空間。
2樓
很明顯,你還沒有搞清楚什么是指針,至于結(jié)構(gòu)體變量和結(jié)構(gòu)體指針,更是很混淆,所以這里不是因?yàn)閿?shù)組的問題。
舉個(gè)例子:
[code=c]
//下面僅僅是定義一個(gè)類型,不會(huì)產(chǎn)生變量,所以不存在分配空間的問題
struct data
{
    int i;
    int j;
};

void main(void)
{
    struct data dat1; //定義一個(gè)struct data類型的變量,和int i同理。
    printf('%d\n', sizeof(struct data)); //8個(gè)字節(jié)
    printf('%d\n', sizeof(dat1));        //8個(gè)字節(jié)

    struct data* pdat1;//定義一個(gè)struct data類型的指針,和int *pi 同理。
    printf('%d\n', sizeof(pdat1));        //4個(gè)字節(jié),就是一個(gè)指針的空間,pdat1并沒有結(jié)構(gòu)體變量的信息。

    pdat1 = (struct data*)malloc(sizeof(struct data)); //申請(qǐng)一個(gè)空間,把該空間地址給pdat1.
    printf('%d\n', sizeof(*pdat1));      //8個(gè)字節(jié)

    struct data dats1[2]; 
    printf('%d\n', sizeof(dats1));     //16個(gè)字節(jié),兩個(gè)data變量,不是data指針。
    dats1[0].i = 20;  //可以直接使用數(shù)組里面的結(jié)構(gòu)體變量
    dats1[0].j = 30;
    
    struct data* dats2[2]; //指針數(shù)組,包含兩個(gè)指針,而不是結(jié)構(gòu)體變量
    printf('%d\n', sizeof(dats2));  //8個(gè)字節(jié),兩個(gè)指針的大小
    dats2[0]->i = 20; //錯(cuò)誤!還沒有給dats2[0] 指針分配空間
    dats2[0]->i = 20; //錯(cuò)誤!還沒有給dats2[0] 指針分配空間
    dats2[0] = (struct data*)malloc(sizeof(struct data)); //分配空間
    dats2[0]->i = 20; //ok
    dats2[0]->i = 20; //ok
}
[/code]
3樓
聲明任何對(duì)象并定義變量,包括指針都會(huì)開辟空間,除了靜態(tài)成員在一個(gè)特別的區(qū),其他的在棧上開辟空間,不用了自動(dòng)清理,用malloc, realloc, calloc, new new[]開辟空間是動(dòng)態(tài)分配空間,在堆上進(jìn)行。值得說明的是,棧空間很小(相對(duì)于堆而言),很'昂貴',但是通常執(zhí)行更快。


在Windows下,一個(gè)進(jìn)程的棧在最高端,向下增長(zhǎng),堆在棧下面,向棧的方向增長(zhǎng),下面是數(shù)據(jù)和代碼。Linux下內(nèi)存布局由開發(fā)工具和操作系統(tǒng)合作負(fù)責(zé),這四個(gè)部分相對(duì)位置布局不確定。


Windows下一個(gè)進(jìn)程的線性地址空間布局:


--------------------
                   |
                   |
棧                 V
                   V
                   V
--------------------
                   ^
                   ^
堆                 |
                   |
                   |
--------------------


其他
4樓
windows默認(rèn)棧大小是1M
棧和堆是共享一內(nèi)存的,可以調(diào)節(jié)它們的比例。來(lái)設(shè)置棧和堆的大小。
不過一般情況下,還是用不著的。。
5樓
[quote]
有人告訴我:
A a[3];  a是A型的,有3個(gè),當(dāng)然分配A乘3大小的空間
A* a;    a是A*型的,當(dāng)然只分配A*大小的空間,而不會(huì)分配A大小的空間


好像跟你說的不太一樣,結(jié)構(gòu)體數(shù)組的話,我在課本里看到的確不用再次申請(qǐng)空間了啊[/quote]


結(jié)構(gòu)體變量分配結(jié)構(gòu)體本身大小的空間,結(jié)構(gòu)體指針分配4個(gè)字節(jié),其實(shí)任何類型的指針都是分配四個(gè)字節(jié)的指針空間。
所以:
A a[3]; //a里面是三個(gè)A變量,所以分配三個(gè)結(jié)構(gòu)體大小
A *a;  //a是一個(gè)指針,分配4個(gè)字節(jié),就算A再大,a也只是4個(gè)字節(jié),因?yàn)槿魏晤愋偷闹羔樁际?個(gè)字節(jié)。要使用a,必須先要對(duì)指針初始化,也即分配空間了。
如:
A *a;
a = (A*)malloc(sizeof(A));

我們完全可以撇開結(jié)構(gòu)體,把問題簡(jiǎn)單化成int類型來(lái)說明這個(gè)指針問題:
int a1[10];
int *a2;

很容易知道,a1是包含10個(gè)int的數(shù)組,大小也就是10*sizeof(int)。我們可以直接使用a1不要在進(jìn)行什么初始化或者分配空間的游戲,因?yàn)閿?shù)組a1里面本身存放的就是int變量本身了。

然后a2,是一個(gè)int*的東西,也就是整型指針,a2不能存放int變量,它只能存放地址,一個(gè)int變量的地址。如果要使用a2,必須首先對(duì)a2初始化,即將它指向一個(gè)int變量的地址,如:
a2 = (int*)malloc(sizeof(int));
或者
int i = 10;
a2 = &i;
所以,malloc函數(shù)的作用是首先聲明一個(gè)變量,然后返回該變量的地址。
所以:a2 = (int*)malloc(sizeof(int)) 的含義就是把該變量的地址賦值給a2,和a = &i 本質(zhì)上并沒有什么不同,只是一個(gè)變量是棧上,一個(gè)是堆上,都是一個(gè)地址賦值。

所以,所謂的分配空間,就是對(duì)指針賦值,把一個(gè)變量的地址賦值給一個(gè)指針。

----------我是萌萌噠分割線----------

很明顯三樓和四樓講的有點(diǎn)底層了,不過其他樓層說的很明白,首先只是分配了指針本身的存儲(chǔ)空間,指針指針還沒有被賦值,通過new或者malloc()語(yǔ)句是為了給結(jié)構(gòu)體變量分配內(nèi)存空間,即為指針賦值,即指針指向的內(nèi)容的信息,便有了指針指向的數(shù)據(jù)內(nèi)容和空間。

----------我是萌萌噠分割線---------- 

原文地址:http://bbs./post-284115.html


    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多