久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 9162|回復(fù): 1
收起左側(cè)

局部變量內(nèi)存分配解疑

[復(fù)制鏈接]
ID:3721 發(fā)表于 2015-1-5 14:23 | 顯示全部樓層 |閱讀模式
     最近在做一個(gè)疲勞試驗(yàn)系統(tǒng),一直在程序執(zhí)行效率上做功夫。也記不清最早是從哪聽說的:定義變量,能定義在函數(shù)內(nèi)絕不定義成全局,能定義在循環(huán)內(nèi)絕不定義成函數(shù)范圍……深以為意!曾經(jīng)犯過一個(gè)錯(cuò)誤,在函數(shù)體內(nèi)定義了一個(gè)和全局變量同名的變量,但在修改注釋的時(shí)候不小心將這個(gè)局部變量的生命給//掉了……編譯無錯(cuò),執(zhí)行總是不對,弄了很久才發(fā)現(xiàn)錯(cuò)誤所在,F(xiàn)在寫程序慎之又慎,盡量不使用全局變量,要使用也用規(guī)范的變量命名方式將全局與局部區(qū)分開。今天讀了篇文章,摘錄如下:

一個(gè)由C/C++編譯的程序占用的內(nèi)存分為以下幾個(gè)部分
1、棧區(qū)(stack)— 由編譯器自動(dòng)分配釋放 ,存放函數(shù)的參數(shù)值,局部變量的值等。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。
2、堆區(qū)(heap) — 一般由程序員分配釋放, 若程序員不釋放,程序結(jié)束時(shí)可能由OS回收 。注意它與數(shù)據(jù)結(jié)構(gòu)中的堆是兩回事,分配方式倒是類似于鏈表,呵呵。
3、全局區(qū)(靜態(tài)區(qū))(static)—,全局變量和靜態(tài)變量的存儲(chǔ)是放在一塊的,初始化的全局變量和靜態(tài)變量在一塊區(qū)域, 未初始化的全局變量和未初始化的靜態(tài)變量在相鄰的另一塊區(qū)域。 - 程序結(jié)束后有系統(tǒng)釋放
4、文字常量區(qū) —常量字符串就是放在這里的。 程序結(jié)束后由系統(tǒng)釋放
5、程序代碼區(qū)—存放函數(shù)體的二進(jìn)制代碼。
一個(gè)正常的程序在內(nèi)存中通常分為程序段,數(shù)據(jù)端和堆棧三部分。程序段里放著程序的機(jī)器碼和只讀數(shù)據(jù),這個(gè)段通常是只讀,對它的寫操作是非法的。數(shù)據(jù)段放的是程序中的靜態(tài)數(shù)據(jù)。動(dòng)態(tài)數(shù)據(jù)則通過堆棧來存放。在內(nèi)存中,它們的位置如下:
+------------------+ 內(nèi)存低端
| 程序段 |
|------------------|
| 數(shù)據(jù)段 |
|------------------|
| 堆  棧  |
+------------------+ 內(nèi)存高端
堆棧是內(nèi)存中的一個(gè)連續(xù)的塊。一個(gè)叫堆棧指針的寄存器(SP)指向堆棧的棧頂。堆棧的底部是一個(gè)固定地址。堆棧有一個(gè)特點(diǎn)就是,后進(jìn)先出。也就是說,后放入的數(shù)據(jù)第一個(gè)取出。它支持兩個(gè)操作,PUSH和POP。PUSH是將數(shù)據(jù)放到棧的頂端,POP是將棧頂?shù)臄?shù)據(jù)取出。
在高級語言中,程序函數(shù)調(diào)用和函數(shù)中的臨時(shí)變量都用到堆棧。為什么呢?因?yàn)樵谡{(diào)用一個(gè)函數(shù)時(shí),我們需要對當(dāng)前的操作進(jìn)行保護(hù),也為了函數(shù)執(zhí)行后,程序可以正確的找到地方繼續(xù)執(zhí)行,所以參數(shù)的傳遞和返回值也用到了堆棧。通常對局部變量的引用是通過給出它們對SP的偏移量來實(shí)現(xiàn)的。另外還有一個(gè)基址指針(FP,在Intel芯片中是BP),許多編譯器實(shí)際上是用它來引用本地變量和參數(shù)的。通常,參數(shù)的相對FP的偏移是正的,局部變量是負(fù)的。
當(dāng)程序中發(fā)生函數(shù)調(diào)用時(shí),計(jì)算機(jī)做如下操作:首先把參數(shù)壓入堆棧;然后保存指令寄存器(IP)中的內(nèi)容,做為返回地址(RET);第三個(gè)放入堆棧的是基址寄存器(FP);然后把當(dāng)前的棧指針(SP)拷貝到FP,做為新的基地址;最后為本地變量留出一定空間,把SP減去適當(dāng)?shù)臄?shù)值。
在函數(shù)體中定義的變量通常是在棧上,用malloc, calloc, realloc等分配內(nèi)存的函數(shù)分配得到的就是在堆上。在所有函數(shù)體外定義的是全局量,加了static修飾符后不管在哪里都存放在全局區(qū)(靜態(tài)區(qū)),在所有函數(shù)體外定義的static變量表示在該文件中有效,不能extern到別的文件用,在函數(shù)體內(nèi)定義的static表示只在該函數(shù)體內(nèi)有效。另外,函數(shù)中的"adgfdf"這樣的字符串存放在常量區(qū)。
……
    寫得我是心里癢癢啊……太好了!以前我有一個(gè)錯(cuò)誤認(rèn)識(shí),示例:
void    aaa()
{
    int i;
    for ( i = 0; i < 100; ++ i )
    {
        int j;
        j = i;
    }
}

我總以為調(diào)用函數(shù)時(shí) i 聲明并分配內(nèi)存一次,而 j 每循環(huán)一次分配一次內(nèi)存。恐怕是和變量作用域混淆了。以前寫程序不用太過關(guān)心效率,聲明在循環(huán)里還是循環(huán)外都不以為意,執(zhí)行起來也無甚差別?涩F(xiàn)在,循環(huán)次數(shù)更加巨大,還要求在極短時(shí)間內(nèi)執(zhí)行完畢……我有點(diǎn)慌咯,我的局部變量假如還不是系統(tǒng)變量類型而是我自己聲明的類……那光構(gòu)造和析構(gòu)都要人老命了……我到底是不是庸人自擾呢?
寫程序試試吧……
.h
class TForm1
{
public:  
    void    aaa();
};

.cpp
void    TForm1::aaa()
{
    int i = 0;
    for ( i; i < 100; ++ i )
    {
        int j;
        j = i;
    }
}

主函數(shù)省略,也就是調(diào)用aaa()。然后第一次主動(dòng)打開CPU觀察器……居然是第一次,寫了快4年程序的第一次!我想被人知道我得被鄙視個(gè)半死……幸好以前8086匯編學(xué)得還行,單片機(jī)也一直堅(jiān)持用匯編編程,有這些基礎(chǔ),看起來也不是很難:


感謝上面說的那篇“神作”!可愛的 add esp,-0x08 原來一早就分配好區(qū)域了……[ ebp-0x04 ]就是i,[ ebp-0x08 ]就是j。感謝偉大的編譯器幫我們干完這些……看來我是杞人憂天了。

以前一直以為變量的內(nèi)存分配就是“new”一塊內(nèi)存……大錯(cuò)特錯(cuò)啊……棧區(qū)就擺在那,局部變量若直接聲明,分配個(gè)P內(nèi)存。但也由于棧區(qū)大小有限制,所以終于明白了一句話:優(yōu)先用vector管理數(shù)組,堆是不限制咱的,vector本身就是幾個(gè)指針而已。于是又明白了一點(diǎn)……以前在函數(shù)內(nèi)建一個(gè)超大數(shù)組編譯出錯(cuò),不是內(nèi)存不夠,是棧區(qū)限制,以前還以為這是數(shù)組本身的特性所致。
    以前夜郎自大了……還是虛心學(xué)習(xí)吧……

回復(fù)

使用道具 舉報(bào)

ID:79197 發(fā)表于 2015-5-8 11:02 | 顯示全部樓層
好貼,mark一下,以后繼續(xù)學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 草草在线观看 | 久久精品99久久久久久 | 久久av影院| 日本激情网 | 欧美日本在线 | www.狠狠操.com | 黄色免费视频 | 成人日韩在线 | 韩国精品一区 | 久久精品观看 | 日本精品网站 | 三级在线观看 | 亚洲国产成人精品女人久久久 | 国模无码大尺度一区二区三区 | 中文字幕二区 | 九九久久久 | 福利精品 | 99热这里 | 欧美极品在线 | 欧美日韩一二三 | 国产欧美综合一区二区三区 | 日韩成人av在线 | 成人深夜福利 | 日本a v在线播放 | 玖草视频 | 一级黄色免费看 | 欧美日韩国产一区二区 | 久草精品视频 | 99热在线免费观看 | 国产一级在线视频 | 老司机午夜免费精品视频 | 成av人片一区二区三区久久 | 日韩精品一区二区三区免费视频 | 中文一级片 | 日本久久视频 | 国产亚洲欧美在线 | 天天色影院 | 欧美精品一区二区在线观看 | 亚洲一区二区三区中文字幕 | 91视频一区二区三区 | 午夜aaa|