2011-11-29 48 views
3

我接觸到指針int* i,其中我只知道它的內存已分配,但不確定它是否已被初始化爲某個整數。如何檢查分配的內存是否被初始化

如果我嘗試尊重它,會發生什麼?換句話說,我應該如何檢查它是否被初始化?如果不是,我想爲該地址分配一個整數值;否則我什麼都不做。

+2

如果內存分配給它,它初始化,但可能會因內存是如何分配的有隨機垃圾數據。 – birryree

+0

可能重複:http://stackoverflow.com/questions/1576300/checking-if-a-pointer-is-allocated-memory-or-not – jasso

+1

雷蒙德陳先生說[IsBadXxxPtr的確可以稱爲CrashProgramRandomly(HTTP:// blogs.msdn.com/b/oldnewthing/archive/2006/09/27/773741.aspx) – ephemient

回答

5

定義「初始化」。總是會有一些價值,你無法判斷這個值是垃圾還是整數,因爲任何32位的垃圾都會產生一些價值。你可以解除引用它,沒問題。

0

我接觸到的指針INT * 1,其中我只知道它的內存是 分配,但我不知道它已被初始化爲某個整數或 沒有。

如果我被分配爲一個指針,並沒有初始化,你會得到一個段違反。如果我是分配和初始化一些整數X ...即

int X = SOMEVALUE; 

    int* i; 
    i = &X; // It would seem silly to malloc a single int... 

它被初始化當且僅當X被初始化。如果您知道它指向的值的某些預期範圍,那麼建議您在使用之前執行邊界檢查...

如果我嘗試遵從它,會發生什麼?換句話說,我應該如何檢查它是否被初始化?如果不是,我想 爲該地址分配一個整數值;否則我什麼都不做。

我的典型做法是將指針初始化爲0或NULL,直到我有一個真正的值來提供它們。在此之前調用somesort的* X *頁頭功能......那麼,如果它的任何地方我會嘗試使用它......我做了...

if (myPtr == NULL) 
{ 
printf("Run failure handling code...\r\n"); 
return FUNC_FAILED_CONST; 
} 

但我必須要更多的信息,以瞭解你的情況....

0

良好的編程習慣包括將NULL分配給未初始化的指針。如果你正在處理別的地方的指針,通常檢查它以確保它不是NULL。你的情況:

if (i != NULL) 
    *i = the_int_you_assign; 

但是,如果處理它沒有特定的方式,你不能在良好的編程習慣算的話,你真的不能爲自己辯護。

0

i通常是整數(通常爲int)對象的名稱。調用指針i令人困惑。

因此,讓我們假設你有

int *p; 

你說「它的內存分配」。你指的是指針對象本身的內存(當你聲明p時分配的內存),還是指它指向的int對象的內存?

無論哪種情況,您都無法判斷它是否已被初始化。

如果p具有靜態存儲持續時間,則它的初始值(在沒有顯式的初始化的)是一個空指針;它沒有指向任何東西。否則,它的初始值是垃圾,除了爲它分配一些有效值之外,你不能安全地執行。

另一方面,如果您的意思是p已被初始化爲指向一些int對象,但該對象可能已經初始化,也可能未初始化,那麼您也有類似的問題。如果您有:

int *p; 
p = malloc(sizeof *p); 
if (p == NULL) { 
    /* malloc() failed! */ 
    exit(EXIT_FAILURE); 
} 

然後p指向一個分配int對象,但該對象的值是垃圾。在大多數系統中,您可以安全地訪問該值(*p) - 但這樣做毫無意義。但有可能int具有陷阱表示;如果是這樣,只是訪問*p的值具有未定義的行爲,並可能導致程序崩潰。優化編譯器可以在未定義的對象存在的情況下做出意想不到的事情;它可以假設它已被初始化爲某個值,並且不費心去實際獲取存儲值。

沒有特殊的值,標記,或用於未初始化的int對象標誌。程序員完全可以確保任何對象在嘗試訪問它之前具有有效的值。

所以你問的;(在C. C是不是這些語言之一當然,很多這些語言的實現都寫(非常仔細地)一些語言跟蹤這些東西給你。)錯誤的問題。如果你不知道一個對象是否已經被初始化,那麼解決方案是找出(邏輯上,當你編寫代碼時,而不是在程序執行期間)是否已經初始化。這樣做的最佳方法通常是確保已初始化爲

如果你試圖做類似下面的僞代碼:

if (/* *p has been initialized */) { 
    do something with *p; 
} 
else { 
    do something else; 
} 

,那麼你就錯了。相反:

/* Ensure p points to a valid int object */ 
*p = some_value; 
/* Now you *know* *p has been initialized */ 
do something with *p; 
0

您也可以在這樣的重新定義malloc的方式,它會分配的內存塊,並通過使用這樣的宏觀其初始化一次零個字節:

#define malloc(p, size) do {if (p != NULL) {p=malloc(size); memset(p, 0, size);}} while(0); 

或者如果你喜歡在條款的malloc可以重新定義的calloc

#define malloc(p, elCount , elSize) do {if (p != NULL) {p=calloc(elCount,elSize);}} while(0); 

通過迫使這種結構,你一定會認爲它使用的malloc()任何程序員 - 還初始化內存正確,以便沒有指針顯示垃圾數據。

+0

爲什麼你比'calloc'更喜歡這個? – jasso

+0

我不知道。是的 - 'malloc()'宏可以用'calloc'來寫。這只是一個例子,如何重寫標準的malloc函數,以便如果開發人員試圖使用* malloc *的舊定義 - 他們得到關於不同malloc簽名的編譯時錯誤,因此被迫使用calloc()或重新定義正確malloc()或者他們想欺騙 - 他們也可以將宏重新定義爲標準(但我不指望這一點,因爲在C中你有很多可能性來欺騙所有的東西:-(所以必須是真誠地開發的某種程度的協議) –

+0

對不起,我有點不清楚,我的意思是,如果你想將malloc定義爲一個像calloc一樣的宏,是否有任何偏好爲什麼在宏中使用memset而不是在宏中使用calloc? – jasso

相關問題