精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

C程序中常見的與內存相關的錯誤及其解決辦法

STM32嵌入式開發 ? 來源:STM32嵌入式開發 ? 2023-06-14 17:13 ? 次閱讀

C語言入門程序員來說,管理和使用虛擬存儲器可能是個困難的,容易出錯的任務。與存儲器有關的錯誤屬于那些最令人驚恐的錯誤,因為它們經常在時間和空間上,都在距錯誤源一段距離之后,才表現出來。

將錯誤的數據編寫到錯誤的位置,你的程序可能在最終失敗之前運行了好幾個小時,且使程序中止的位置距離錯誤的位置已經很遠了。

1、間接引用壞指針

在進程的虛擬地址空間中有較大的漏洞,沒有映射到任何有意義的數據。如果我們試圖間接引用一個指向這些洞的指針,那么操作系統就會以段異常終止我們的程序。

而且,虛擬存儲器的某些區域是只讀的。試圖寫這些區域將造成以保護異常終止這個程序。

間接引用壞指針的一個常見示例是經典的scanf錯誤。假設我們想要使用scanf從stdin讀一個整數到變量。做這件事情正確的方法是傳遞給scanf一個格式串和變量的地址:

ea36476a-0a92-11ee-962d-dac502259ad0.png ????

然而,對于c語言程序員初學者而言,很容易傳遞val的內容,而不是它的地址:

ea4a0b38-0a92-11ee-962d-dac502259ad0.png ????

在這種情況下,scanf將把val的內容解釋為一個地址,并試圖將一個字寫到這個位置。在最好的情況下,程序立即以異常終止。

在最糟糕的情況下,val的內容對應于虛擬存儲器的某個合法的讀/寫區域,于是我們就覆蓋了存儲器,這通常會在相當以后造成災難性的、令人困惑的后果。

2、讀未初始化的存儲器

雖然.bss存儲器位置(諸如未初始化的全局C變量)總是被加載器初始化為零,但是對于堆存儲器卻并不是這樣的。一個常見的錯誤就是假設堆存儲器被初始化為零:

ea61e03c-0a92-11ee-962d-dac502259ad0.png ????

在這個示例中,程序員不正確地假設向量y被初始化為零。正確的實現方式是在for循環時將y[i]設置為零,或使用calloc。

3、允許棧緩沖區溢出

如果一個程序不檢查輸入串的大小就寫入棧中的目標換成區,那么這個程序就會有緩沖區溢出錯誤。例如,下面的函數就有緩沖區錯誤,因為gets函數拷貝一個任意長度的串到緩沖區。為了糾正這個錯誤,我們必須使用fgets函數,這個函數限制了輸入串的大?。?br />
ea77efda-0a92-11ee-962d-dac502259ad0.png

4、假設指針和它們指向的對象是相同大小的

一種常見的錯誤是假設指向對象的指針和它們所指向的對象是相同大小的:

ea8547ca-0a92-11ee-962d-dac502259ad0.png ????

這里的目的是創建一個由n個指針組成的數組,每個指針都指向一個包含m個int的數組。然而,因為程序員將int **A = (int **)malloc(n * sizeof(int));中將sizeof(int)寫成了sizeof(int),代碼實際創建的是一個int的數組。這段代碼只有在int和指向int的指針大小相同的機器上運行良好。

但是,如果我們在像Alpha這樣的機器上運行這段代碼,其中指針大于int,那么在for(i = 0; i < n; i++)? A[i] = (int *)malloc(m * sizeof(int));將寫到超過A數組末端的地方。因為這些字中的一個很可能是分配塊的邊界標記腳部,所以我們可能不會發現這個錯誤,而沒有任何明顯的原因。

5、造成錯位錯位

錯位錯誤是另一種很常見的覆蓋錯誤發生的原因:

ea991b7e-0a92-11ee-962d-dac502259ad0.png ????

這是前面程序的另一個版本。這里我們創建了一個n個元素的指針數組,但是隨后試圖初始化這個數組的n+1個元素,在這個過程中覆蓋了A數組后面的某個存儲器。

6、引用指針,而不是它所指向的對象

如果我們不太注意C操作符的優先級和結合性,我們就會錯誤地操作指針,而不是期望操作指針所指向的對象。比如,考慮下面的函數,其目的是刪除一個有*size項的二叉堆里的第一項,然后對剩下的*size-1項重新建堆。

eaa59a70-0a92-11ee-962d-dac502259ad0.png ???

*size—目的是減少size指針指向的整數的值。然而,因為一元—和*運算符優先級相同,從右向左結合,所以代碼實際減少的是指針自己的值,而不是它所指向的整數的值。

如果幸運的話,程序會立即失敗,但是更有可能發生的是,當程序在它執行過程的很后面產生一個不正確的結果時,我們只能在那里抓腦袋了。這里的原則是如果你對優先級和結合性有疑問,就使用括號。使用表達式(*size)--。

7、誤解指針運算

另一種常見的錯誤是忘記了指針的算術操作是以它們指向的對象的大小為單位來進行的,而這種大小單位并不一定是字節。例如,下面函數的目的是掃描一個int的數組,并返回一個指針,指向val的首次出現:

eaadef90-0a92-11ee-962d-dac502259ad0.png

8、引用不存在的變量

沒有太多經驗的C程序員不理解棧的規則,有時會引用不再合法的本地變量,如下列所示:

eac44b8c-0a92-11ee-962d-dac502259ad0.png ????

這個函數返回一個指針,指向棧里的一個局部變量,然后彈出它的棧幀。盡管p仍然指向一個合法的存儲器地址,但是它已經不再指向一個合法的變量了。

當以后在程序中調用其他函數時,存儲器將重用它們的幀棧。后來,如果程序分配某個值給*p,那么它可能實際正在修改另一個函數的幀棧中的一個條目,從而帶來潛在地災難性的、令人困惑的后果。

9、引用空閑堆塊中的數據

一個相似的錯誤是引用已被釋放了的堆塊中的數據。如下面的示例,示例中分配了一個整數數組x,之后釋放了塊x,最后又引用了它。

ead02362-0a92-11ee-962d-dac502259ad0.png

10、引起存儲器泄漏

存儲器泄漏是緩慢、隱形的殺手,當程序員不小心忘記釋放已分配塊,而在堆里創建了垃圾時,會發生這種問題。例如,下面的函數分配了一個堆塊x,然后不釋放它就返回。

eae5f37c-0a92-11ee-962d-dac502259ad0.png ????

如果leak經常被調用,堆里就會充滿了垃圾,最糟糕的情況下,會占有整個虛擬地址空間。對于像守護進程和服務器這樣的程序來說,存儲器泄漏是特別嚴重的,根據定義這些程序是不會終止的。




審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 存儲器
    +關注

    關注

    38

    文章

    7452

    瀏覽量

    163606
  • C語言
    +關注

    關注

    180

    文章

    7598

    瀏覽量

    136198
  • 虛擬機
    +關注

    關注

    1

    文章

    908

    瀏覽量

    28093

原文標題:C程序中常見的與內存相關的錯誤

文章出處:【微信號:c-stm32,微信公眾號:STM32嵌入式開發】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    C程序中常見的與內存相關錯誤

    C語言入門程序員來說,管理和使用虛擬存儲器可能是個困難的,容易出錯的任務。與存儲器有關的錯誤屬于那些最令人驚恐的錯誤,因為它們經常在時間和空間上,都在距
    發表于 06-14 17:13 ?346次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>程序</b><b class='flag-5'>中常見</b>的與<b class='flag-5'>內存</b><b class='flag-5'>相關</b>的<b class='flag-5'>錯誤</b>

    聲卡硬件維修的常見問題及解決辦法

    聲卡硬件維修的常見問題及解決辦法 常見故障一:聲卡無聲   出現這種故障常見的原因有:
    發表于 02-23 14:25 ?2530次閱讀

    垂直熱風整平中常見問題解決辦法

    垂直熱風整平中常見問題解決辦法   熱風整平又叫噴錫,它的工作原理是利用熱風將印制板表面及孔內多余焊料去掉,剩余焊料均
    發表于 03-02 09:35 ?782次閱讀

    開發中常遇電磁兼容EMC問題及解決辦法

    開發中常遇電磁兼容EMC問題及解決辦法 下面產品開發中常見的一些EMC問題: 一
    發表于 04-17 11:32 ?728次閱讀

    物理內存使用率高的原因及解決辦法

    主要講解的就是物理內存使用率高的原因以及他的解決辦法。導致物理內存使用率高有幾種可能,而最常見的則有兩種:一是安裝不好的程序
    發表于 05-03 17:14 ?9341次閱讀
    物理<b class='flag-5'>內存</b>使用率高的原因及<b class='flag-5'>解決辦法</b>

    Absinthe2.0越獄iOS5.1.1常見錯誤解決辦法

    Absinthe2.0越獄中可能會遇到一些問題,本內容介紹了Absinthe2.0越獄iOS5.1.1常見錯誤解決辦法
    發表于 09-12 15:03 ?4672次閱讀

    Matlab編程常見錯誤解決辦法

    Matlab編程常見錯誤解決辦法求人不如求己
    發表于 03-16 15:58 ?0次下載

    一文知道Zynq平臺運行SDK程序錯誤解決辦法

    Zynq平臺運行SDK程序錯誤解決辦法,具體的跟隨小編一起來了解一下。
    的頭像 發表于 07-14 06:05 ?8031次閱讀

    KEIL C編譯器中常見的警告與錯誤信息的詳細解決辦法資料概述

    本文檔的主要內容詳細介紹的是KEIL C編譯器中常見的警告與錯誤信息的詳細解決辦法資料概述。
    發表于 11-07 17:43 ?14次下載

    內存條兼容異常問題的原因及其解決辦法

    經常使用電腦的朋友都知道,電腦如果出現滴滴聲的 電腦開機 故障就是內存條出現了問題。但是如果類似迅雷等軟件突然出現問題時,大多數朋友可能就不會想到是由于內存出現了兼容性的問題了。下面,我就向大家介紹一下內存條兼容異常問題的原因
    發表于 06-14 10:53 ?1.1w次閱讀

    C語言常見內存錯誤及解決方法

      本文將帶您了解一些良好的和內存相關的編碼實踐,以將內存錯誤保持在控制范圍內。內存錯誤
    的頭像 發表于 02-14 13:10 ?3250次閱讀

    java內存溢出的幾種原因和解決辦法

    內存,但是如果程序中存在內存泄漏(Memory Leak)或者使用不當的數據結構等問題,仍然有可能導致內存溢出。下面將詳細介紹Java內存
    的頭像 發表于 11-23 14:44 ?6049次閱讀

    codeblocks環境錯誤解決辦法

    CodeBlocks是一款常用的集成開發環境,用于編寫、編譯和調試CC++等程序。然而,有時在使用CodeBlocks時可能會遇到一些錯誤或問題。本文將為你提供一些
    的頭像 發表于 11-26 09:37 ?6685次閱讀

    常見MCU故障及解決辦法

    微控制器單元(MCU)是現代電子設備中的核心組件,負責處理和控制各種功能。然而,由于各種原因,MCU可能會出現故障。以下是一些常見的MCU故障及其解決辦法: 1. 電源問題 故障現象: MCU無法
    的頭像 發表于 11-01 13:41 ?614次閱讀

    RS232串口通信中常見問題及解決辦法

    RS232串口通信中常見問題及解決辦法主要包括以下幾個方面: 一、物理連接問題 問題 :串口線未插穩或接口松動。 解決辦法 :重新插拔串口線,確保連接牢固。同時檢查插頭和針腳是否損壞,如有損壞需更換
    的頭像 發表于 11-21 09:32 ?306次閱讀