我有N個靜態分配的結構。檢查指針是否指向有效結構
struct exemple{
...
}
struct exemple array[N];
struct exemple *test_ptr = 0x3; /* random address */
我可以檢查test_prt是否指向有效地址?即它指向分配的一個「結構示例」。
我有N個靜態分配的結構。檢查指針是否指向有效結構
struct exemple{
...
}
struct exemple array[N];
struct exemple *test_ptr = 0x3; /* random address */
我可以檢查test_prt是否指向有效地址?即它指向分配的一個「結構示例」。
只能通過執行pointer != NULL
來檢查指針是否有效,因爲除NULL之外的任何內容均被有效指針處理。
你的情況,檢查你的指針指向任何你數組項,你只能做到這一點:
size_t i = 0;
int isValid = 0;
for (i = 0; i < N; i++) {
if (test_ptr == &array[i]) {
isValid = 1;
break;
}
}
if (isValid) {
//Pointer points to one of your array entry
}
但在一般情況下,你不能只是指針指向測試特定的有效位置您。由你來負責照顧它所指的地方。它也可以有非空值,但指向無效的位置,例如:
int* ptr = malloc(10); //Now points to allocated memory
*ptr = 10;
free(ptr); //Free memory
*ptr = 10; //Undefined behaviour, it still points to the same address but
//we don't know what will happen. Depends on implementation
你不能。你必須知道。如果你正確地管理你的指針,這不是一個問題。一個好習慣就是一旦銷燬它們指向的對象,就總是設置指向0
/NULL
的指針。然後,您可以僅使用if (ptr)
或if (!ptr)
(或更詳細:if (ptr == NULL)
/if (ptr != NULL)
)進行測試。
需要注意的是你的最後分配
struct exemple *test_ptr = 0x3; /* random address */
是無效。你不能給一個指針賦一個整數。但你可以鑄它的指針類型;
struct exemple *test_ptr = (struct exemple *)0x3; /* random address */
結果將取決於您的實施/系統。
沒有語言方法,但在某些情況下,您可以嘗試在結構的某些點處具有一些已知值。如果指向的內存位置具有這些值,則可以將其視爲有效 - 但當然,您沒有任何擔保。但是當你創建結構時,你需要編寫自己的函數,以及何時將其銷燬(通過在釋放內存之前填充零)。這是一個非常周的解決方法 - 但是如果你連接另一個度量並接受開銷,它會降低不正確的程序行爲的概率。
有時它被稱爲安全cookie。
當然有可能使它變得更加複雜 - 在某些位置上,只有這些餅乾有偏移量。它使內存中的隨機位置不太可能具有這樣的數據鏈:)
一般來說,不,你不能測試指針是否有效。
但是,如果你想知道,如果一個指針指向一個數組的元素,您可以:
if(test_ptr >= &array[0] && test_ptr < &array[N]
&& ((intptr_t)test_ptr - (intptr_t)array)%((intptr_t)(&array[1]) - (intptr_t)array) == 0) {
// test_ptr points to an element of array
}
這工作,因爲數組連續地分配。
我不知道我是否正確地得到您的問題。
如果你想知道,如果一個指針指向某種類型的結構(投我的結構,以void *
,反之亦然,例如),我做了下道:
#include <assert.h>
struct my_struct {
#ifndef NDEBUG
#define MY_STRUCT_MAGIC 0x1234abcd
uint64_t magic;
#endif
int my_data;
};
void init_struct(struct my_struct *s, int t_data) {
#ifdef MY_STRUCT_MAGIC
s->magic = MY_STRUCT_MAGIC;
#endif
s->my_data = t_data;
}
my_struct *my_struct_cast(void *vs) {
my_struct *s = vs;
#ifdef MY_STRUCT_MAGIC
assert(MY_STRUCT_MAGIC == s->magic);
#endif
return s;
}
它有一個由於包含了const-casting,所以代碼更多一點,但我認爲你明白了。
如果你想知道,如果test_ptr指向阿雷成員,你必須檢查這種方式:test_ptr >= array && test_ptr < &array[sizeof(array)/sizeof(array[0])])
。如果指針來自void,char或者某種危險的ariyhmetic,那麼你也可以檢查test_ptr % sizeof(array[0])
如果你想知道指針是否指向你的程序「曾經分配過」的有效內存,你將不得不攔截分配函數,保存返回的塊指針大小,並像上例那樣進行計算。
我知道我可以做陣列檢查,但我想知道是否有更多的直接方法。謝謝 – alessiovolpe
@alessiovolpe不幸的是,沒有,這就是爲什麼C是控制語言:) – tilz0R
這對於大型陣列來說效率非常低。 **有更直接的方式,@alessiovolpe。 – alain