程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 【編程好習慣】使用sizeof減少內存操作失誤

【編程好習慣】使用sizeof減少內存操作失誤

編輯:關於C語言

在編程過程中,在大量的情況下需要使用memset()函數對內存進行置零初始化除了這裡說的memset()其實很多函數,比如snprintf()、strncpy()等都可以借用這裡談到的方法),以下三種情況是在工作中經常在這方面碰到的錯誤,大部分錯誤是因為疏忽而造成的。
例1

char *buf [FAIP_WITHDOT_MAX_LEN+1];
memset (buf, 0, FAIP_WITHDOT_MAX_LEN + 1);

例2

#define DIGEST_LEN 17
#define DIGEST_MAX 16

char digest [DIGEST_MAX];
memset (digest, 0, DIGEST_LEN);

例3

dll_node_t *p_node = malloc (sizeof (dll_node_t));
if (p_node == 0)
return;
memset (p_node, 0, sizeof (dll_t));


下面示例了如何采用一般化的方法更正上面的三種錯誤。
例1修訂1

char *buf [FAIP_WITHDOT_MAX_LEN+1];
memset (buf, 0, sizeof (char *) * (FAIP_WITHDOT_MAX_LEN + 1));

例2修訂1

#define DIGEST_LEN 17
#define DIGEST_MAX 16

char digest [DIGEST_MAX];
memset (digest, 0, DIGEST_MAX);

例3修訂1

dll_node_t *p_node = malloc (sizeof (dll_node_t));
if (p_node == 0)
return;
memset (p_node, 0, sizeof (dll_node_t));


需要思考的是,如何在工作中盡可能的避免這類“低級”錯誤。雖然可以通過采用code review的方式增加錯誤的檢出率,但這種效果並不好。更為好一點的方法是程序員養成一定的編程習慣,比如采用這裡將要主張的sizeof()方法就能顯著地降低這類錯誤。下面示例了如何采用sizeof()來更正錯誤。
例1修訂2

char *buf [FAIP_WITHDOT_MAX_LEN+1];
memset (buf, 0, sizeof (buf));

例2修訂2

#define DIGEST_LEN 17
#define DIGEST_MAX 16

char digest [DIGEST_MAX];
memset (digest, 0, sizeof (digest));

例3修訂2

dll_node_t *p_node = malloc (sizeof (dll_node_t));
if (p_node == 0)
return;
memset (p_node, 0, sizeof (*p_node));


這裡所說的采用sizeof()規避錯誤的方法其背後的思想是什麼呢?人的大腦是注定要出錯的,如果在大腦中存有處理同一事務的大量規則或根本沒有規則,那麼往往在處理這一事務時更容易出錯。采用memset()函數對內存初始化就屬於容易出錯的一類事務,因為在指定實際被初始化內存的大小時,一般化的方法是需要根據被初始化內存的上下文來決定傳遞給memset()函數內存大小的具體值。如果采用sizeof()來獲取所需初需化內存的大小並將其固化成編程習慣,那麼就不容易出錯。

對於前面的第一和第二種錯誤,只需要將數組當作sizeof()的參數,而不用關心數組在定義時的大小到底是多少。即使因為需要而更改目標數組的大小,sizeof()仍會返回更改後的實際數組的大小,而不需要對memset()函數的調用做任何的手動更改。對於第三種錯誤,方法是相類似的,只不過要采用sizeof(*xxx)的形式,其中xxx是目標指針變量,比如前面第三個例子中的p_node。

注意到采用sizeof()方法的共性了嗎?都是以需要初始化的目標變量作為sizeof()的參數的,而不是以目標變量的類型或是宏作為其參數,這種方式使得寫出來的程序更加不容易出錯。采用sizeof()方法,對於獲取被初始化內存的大小簡化為只有兩條規則:
1)如果目標變量是一個數組,則采用sizeof(xxx)的格式獲取內存大小,其中的xxx是指數組變量名,顯然這個數組變量可以是嵌套在另一個數據結構中的。
2)如果目標變量是一個數據結構的指針,則采用sizeof(*xxx)獲取內存大小,其中的xxx則是指數據結構指針變量名,而不是數據結構類型。

最後一個問題是,采用sizeof()會降低程序的性能嗎?不會!因為sizeof()是在程序編譯時由編譯器進行計算並最終得出一個數字的,是一個靜態的行為而不是運行時行為。

本文出自 “至簡李雲” 博客,請務必保留此出處http://yunli.blog.51cto.com/831344/227130

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved