目錄
-
- 1:現象
- 2:示例
- 3:原因
- 4:修改
- 5:總結
1:現象
在使用指針的時候經常會發生Segmentation fault。如下所示
2:示例
/*************************************************************************
> File Name: test5.c
> Author: kayshi
> Mail: [email protected]
> Created Time: Mon 07 Dec 2020 06:36:54 PM CST
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct str{
char a;
char *p;
};
void show(struct str *str_s, int num)
{
int i;
for(i = 0; i < num; i++)
{
printf("show: ");
printf("%d ", str_s->a);
printf("%s\n", str_s->p);
str_s++;
}
}
int fun(struct str *str_m, int num)
{
int i;
for(i = 0; i < num; i++)
{
str_m->p = (char *)malloc(5);
str_m->a = i;
strcpy(str_m->p, "hello");
str_m++;
}
show(str_m, num);
return 0;
}
int main()
{
struct str *str_p;
int num = 3;
str_p = (struct str*)malloc(sizeof(struct str)*num);
fun(str_p, num);
}
代碼函數:配置設定一個空間,空間大小是3個struct str這麼大,讓str_p指向這個空間的首位址。在fun種對每個結構體依次進行指派操作。然後使用show函數來列印顯示
執行:發生錯誤
[email protected]:~/code/Test$ ./a.out
Segmentation fault (core dumped)
3:原因
發生這個錯誤的原因是在函數fun中使用了str_m++,然後繼續把str_m傳遞給了函數show中去。原本的意思指派完後把首位址傳遞到函數中去。開始時,str_m指向首位址,由于自加導緻了str_m發生了偏移。偏移之後的位址,是未被配置設定的空間。show再使用偏移後的位址,就會産生段錯誤的現象。
4:修改
隻需要把空間的首位址傳遞給show就可以,那麼利用一個臨時指針變量str_tmp等于str_m,在函數fun中進行3次指派,每次自加。那麼就不會影響str_m。
修改fun函數
int fun(struct str *str_m, int num)
{
int i;
struct str *str_tmp = str_m;
for(i = 0; i < num; i++)
{
str_tmp->p = (char *)malloc(5);
str_tmp->a = i;
strcpy(str_tmp->p, "hello");
str_tmp++;
}
show(str_m, num);
return 0;
}
執行
[email protected]:~/code/Test$ ./a.out
show: 0 hello
show: 1 hello
show: 2 hello
5:總結
發生這種錯誤最可能的原因就是,使用了未正常配置設定的記憶體。