最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺析C語言編程中的數(shù)組越界問題

 更新時(shí)間:2015年11月17日 17:22:09   作者:wind19  
這篇文章主要介紹了淺析C語言編程中的數(shù)組越界問題,通過內(nèi)存空間來討論其導(dǎo)致的程序崩潰問題,需要的朋友可以參考下

因?yàn)镃語言不檢查數(shù)組越界,而數(shù)組又是我們經(jīng)常用的數(shù)據(jù)結(jié)構(gòu)之一,所以程序中經(jīng)常會(huì)遇到數(shù)組越界的情況,并且后果輕者讀寫數(shù)據(jù)不對(duì),重者程序crash。下面我們來分析一下數(shù)組越界的情況:
1) 堆中的數(shù)組越界

因?yàn)槎咽俏覀冏约悍峙涞?,如果越界,那么?huì)把堆中其他空間的數(shù)據(jù)給寫掉,或讀取了其他空間的數(shù)據(jù),這樣就會(huì)導(dǎo)致其他變量的數(shù)據(jù)變得不對(duì),如果是一個(gè)指針的話,那么有可能會(huì)引起crash

2) 棧中的數(shù)組越界

因?yàn)闂J窍蛳略鲩L的,在進(jìn)入一個(gè)函數(shù)之前,會(huì)先把參數(shù)和下一步要執(zhí)行的指令地址(通過call實(shí)現(xiàn))壓棧,在函數(shù)的入口會(huì)把ebp壓棧,并把esp賦值給ebp,在函數(shù)返回的時(shí)候,將ebp值賦給esp,pop先前棧內(nèi)的上級(jí)函數(shù)棧的基地址給ebp,恢復(fù)原?;?,然后把調(diào)用函數(shù)之前的壓入棧的指令地址pop出來(通過ret實(shí)現(xiàn))。

棧是由高往低增長的,而數(shù)組的存儲(chǔ)是由低位往高位存的 ,如果越界的話,會(huì)把當(dāng)前函數(shù)的ebp和下一跳的指令地址覆蓋掉,如果覆蓋了當(dāng)前函數(shù)的ebp,那么在恢復(fù)的時(shí)候esp就不能指向正確的地方,從而導(dǎo)致未可知的情況,如果下一跳的地址也被覆蓋掉,那么肯定會(huì)導(dǎo)致crash。

-------------------------

 壓入的參數(shù)和函數(shù)指針

-------------------------

                        aa[4]

                        aa[3]

合法的數(shù)組空間   aa[2]

                        aa[1]

                        aa[0]

-------------------------

 

###sta.c###

#include <stdio.h>

void f(int ai)
{
int aa[5]={1,2,3};
int i = 1;
for (i=0;i<10;i++)
 aa[i]=i;
printf("f()/n");
}

void main()
{
f(3);
printf("ok/n");
}

 

 

###sta.s###

     .file  "sta.c"                 ;說明匯編的源程序
    .section    .rodata           ;說明以下是只讀數(shù)據(jù)區(qū)
.LC0:
    .string "f()"                  ;"f()" 的類型是string,地址為LC0
    .text                       ;代碼段開始
.globl f                         ;f為全局可訪問
    .type  f, @function            ; f是函數(shù)
f:
    pushl  %ebp
    movl  %esp, %ebp
    subl  $40, %esp
    movl  $0, -24(%ebp)
    movl  $0, -20(%ebp)
    movl  $0, -16(%ebp)
    movl  $0, -12(%ebp)
    movl  $0, -8(%ebp)
    movl  $1, -24(%ebp)
    movl  $2, -20(%ebp)
    movl  $3, -16(%ebp)
    movl  $1, -4(%ebp)
    movl  $0, -4(%ebp)
    jmp   .L2
.L3:
    movl  -4(%ebp), %edx
    movl  -4(%ebp), %eax
    movl  %eax, -24(%ebp,%edx,4)
    addl  $1, -4(%ebp)
.L2:
    cmpl  $9, -4(%ebp)
    jle   .L3
    movl  $.LC0, (%esp)
    call  puts
    leave
    ret
    .size  f, .-f                     ;用以計(jì)算函數(shù)f的大小
    .section    .rodata
.LC1:
    .string "ok"
    .text
.globl main
    .type  main, @function
main:
    leal  4(%esp), %ecx
    andl  $-16, %esp
    pushl  -4(%ecx)
    pushl  %ebp
    movl  %esp, %ebp
    pushl  %ecx
    subl  $4, %esp
    movl  $3, (%esp)
    call  f
    movl  $.LC1, (%esp)
    call  puts
    addl  $4, %esp
    popl  %ecx
    popl  %ebp
    leal  -4(%ecx), %esp
    ret
    .size  main, .-main
    .ident "GCC: (GNU) 4.1.2 20070115 (SUSE Linux)"        ;說明是用什么工具編譯的
    .section    .note.GNU-stack,"",@progbits

 

從main函數(shù)開始?jí)喝雈函數(shù)的參數(shù)開始,堆棧的調(diào)用情況如下

20151117171954436.gif (341×267)

圖1  壓入?yún)?shù)

20151117172018789.gif (315×241)

圖二  通過call 命令壓入下一跳地址 IP

20151117172103760.gif (319×250)

圖三  函數(shù)f 通過pushl   %ebp 把 ebp保存起來

20151117172121305.gif (414×210)

圖四  函數(shù) f 通過movl    %esp, %ebp讓ebp指向esp,這樣esp就可以進(jìn)行修改,在函數(shù)返回的時(shí)候用ebp的值對(duì)esp進(jìn)行恢復(fù)

20151117172136004.gif (407×540)

圖五  函數(shù) f 通過subl    $40, %esp 給函數(shù)的局部變量預(yù)留空間

20151117172152902.gif (418×531)

圖六  int數(shù)組 aa[5]占用了20個(gè)字節(jié)的空間,然后 int i占用了4個(gè)字節(jié)的空間(緊鄰著之前壓入棧的%ebp)

故,如果aa[5]進(jìn)行賦值,則會(huì)把 i 的值覆蓋掉,

如果對(duì)aa[6]進(jìn)行賦值,則會(huì)把 棧中的 %ebp 覆蓋掉,那么在函數(shù) f 返回的時(shí)候則不能對(duì)ebp進(jìn)行恢復(fù),即main函數(shù)的ebp變成了我們覆蓋掉的值,程序不知道會(huì)發(fā)生什么事情,但因?yàn)槲覀兊某绦蚪酉聛頉]有調(diào)用棧中的內(nèi)容,故還是可以運(yùn)行的。

如果對(duì)aa[7]進(jìn)行賦值,則會(huì)把棧中的 %IP 覆蓋掉,在函數(shù) f 返回的時(shí)候就不能正確地找到下一跳的地址,會(huì)crash;

相關(guān)文章

  • OpenCV利用霍夫變換進(jìn)行直線檢測(cè)

    OpenCV利用霍夫變換進(jìn)行直線檢測(cè)

    這篇文章主要為大家詳細(xì)介紹了OpenCV利用霍夫變換進(jìn)行直線檢測(cè),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • VC++的if語句應(yīng)用范圍分析

    VC++的if語句應(yīng)用范圍分析

    這篇文章主要介紹了VC++的if語句應(yīng)用范圍分析,對(duì)VC++初學(xué)者有很好的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2014-08-08
  • 淺談C++內(nèi)存分配及變長數(shù)組的動(dòng)態(tài)分配

    淺談C++內(nèi)存分配及變長數(shù)組的動(dòng)態(tài)分配

    下面小編就為大家?guī)硪黄獪\談C++內(nèi)存分配及變長數(shù)組的動(dòng)態(tài)分配。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-09-09
  • c++動(dòng)態(tài)內(nèi)存空間示例(自定義空間類型大小和空間長度)

    c++動(dòng)態(tài)內(nèi)存空間示例(自定義空間類型大小和空間長度)

    這篇文章主要介紹了c++動(dòng)態(tài)內(nèi)存空間示例,自定義空間類型大小和空間長度,需要的朋友可以參考下
    2014-04-04
  • Qt實(shí)現(xiàn)串口助手

    Qt實(shí)現(xiàn)串口助手

    這篇文章主要為大家詳細(xì)介紹了Qt實(shí)現(xiàn)串口助手,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • C++中實(shí)現(xiàn)子進(jìn)程執(zhí)行和管道通信詳解

    C++中實(shí)現(xiàn)子進(jìn)程執(zhí)行和管道通信詳解

    在這篇博客中,我們將深入探索如何在 C++ 程序中實(shí)現(xiàn)子進(jìn)程的創(chuàng)建與執(zhí)行,以及父子進(jìn)程間的管道通信,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-01-01
  • C++命名空間 namespace詳解

    C++命名空間 namespace詳解

    定義命名空間,使用namespace關(guān)鍵字,后面跟命名空間的名字,然后接一對(duì)花括號(hào){ } 即可,{ }中即為命名空間的成員,這篇文章主要介紹了C++命名空間 namespace,需要的朋友可以參考下
    2023-04-04
  • 詳解C語言初階之函數(shù)

    詳解C語言初階之函數(shù)

    這篇文章主要介紹了C語言中的初階函數(shù),介紹了其相關(guān)概念,具有一定參考價(jià)值。需要的朋友可以了解下,希望能夠給你帶來幫助
    2021-11-11
  • C語言排序算法之冒泡排序?qū)崿F(xiàn)方法【改進(jìn)版】

    C語言排序算法之冒泡排序?qū)崿F(xiàn)方法【改進(jìn)版】

    這篇文章主要介紹了C語言排序算法之冒泡排序?qū)崿F(xiàn)方法,結(jié)合具體實(shí)例形式分析了C語言實(shí)現(xiàn)的基本冒泡排序?qū)崿F(xiàn)方法及增設(shè)flag標(biāo)志位的改進(jìn)型算法,需要的朋友可以參考下
    2017-09-09
  • C++ Invalidaterect()函數(shù)作用案例詳解

    C++ Invalidaterect()函數(shù)作用案例詳解

    這篇文章主要介紹了C++ Invalidaterect()函數(shù)作用案例詳解,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08

最新評(píng)論

盱眙县| 高密市| 北碚区| 富平县| 黎川县| 文登市| 通城县| 加查县| 紫金县| 错那县| 安宁市| 波密县| 安阳县| 焦作市| 敦煌市| 西华县| 长岛县| 祁阳县| 道真| 灵台县| 南京市| 芦溪县| 宾川县| 施甸县| 大渡口区| 农安县| 光山县| 青州市| 阜南县| 方山县| 灵石县| 远安县| 怀集县| 张北县| 莱州市| 鄄城县| 汶川县| 滨海县| 山东省| 湖州市| 新蔡县|