[英]Checking NULL Pointer In C Doesn't Work
我有一個函數可以返回多個間接指針,如下所示:
typedef struct {
int id;
char *name;
} user;
user **myfn(int users_count) {
user **a;
a = malloc(sizeof(user) * user_counts);
for(int i = 0 ; i<user_counts ; i++) {
*(a+i) = malloc(sizeof(user));
(*(a+i))->id = 1;
(*(a+i))->name = malloc(sizeof(char) * 25);
strncpy((*(a+i))->name, "Morteza", 25); // just for example
}
return a;
}
現在,當我想在main函數中檢索此結果時,它將顯示所有用戶名,但最后它將遇到Segmentation fault
錯誤。
int main() {
user **a = myfn(10);
int i = 0;
while((*(a+i)) != NULL) {
printf("ID: %d \t %s\n", (*(a+i))->id, (*(a+i))->name);
i++;
}
}
結果:
ID: 1 Morteza
ID: 2 Morteza
...
...
ID: 10 Morteza
Segmentation fault (core dumped)
為什么while
condition
不能正常工作?
首先,
a = malloc(sizeof(user) * user_counts);
有一個問題-您想分配user_counts
指向 user
實例,而不是user
實例,因此該行應為
a = malloc(sizeof(user *) * user_counts);
但是,有一種更簡便的方法sizeof
運算符可以將表達式作為參數以及類型名稱。 因此,您可以將該行重寫為
a = malloc( sizeof *a * user_counts );
表達式 *a
類型為user *
,因此sizeof *a
等效於sizeof (user *)
。 這使您的工作變得更簡單,因為您不必弄清楚a
指向的類型-使編譯器完成艱苦的工作。
您應該始終檢查malloc
調用的結果。
a = malloc( sizeof *a * users_count );
if ( a )
{
// do stuff with a
}
其次重要的是,不要使用*(a+i)
索引到a
-用a[i]
來代替。 使事情更容易閱讀。 所以,
*(a+i) = malloc(sizeof(user));
(*(a+i))->id = 1;
(*(a+i))->name = malloc(sizeof(char) * 25);
變成
a[i] = malloc(sizeof *a[i]);
if ( a[i] )
{
a[i]->id = 1;
a[i]->name = malloc(sizeof *a[i]->name * 25);
}
else
{
/* deal with memory allocation failure */
}
現在,解決您的實際問題。 您的代碼由於以下原因之一而崩潰:
malloc
的a
失敗了,所以你崩潰的使用第一線a[i]
; a[i]
之一的malloc
失敗,因此您崩潰a[i]->id = 1
; users_count
的元素a
- 沒有 a[i]
為NULL
,所以你過去循環的數組的最后一個元素,並嘗試取消引用緊隨其后的對象,這是最有可能不是一個有效的指針。 除了在每個malloc
調用之后添加檢查之外,您還應該基於users_count
循環:
for ( i = 0; i < users_count; i++ )
printf("ID: %d \t %s\n", a[i]->id, a[i]->name);
或者,你需要分配一個額外的元素a
並將其設置為NULL
:
a = malloc( sizeof *a * (users_count + 1) );
if ( a )
{
a[users_count] = NULL;
for ( i = 0; i < users_count; i++ )
...
}
注意, calloc
將所有分配的內存初始化為0,因此您可以使用它,而不必擔心將元素顯式設置為NULL
:
a = calloc( users_count + 1, sizeof *a );
if ( a )
{
for ( i = 0; i < users_count; i++ )
...
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.