段錯誤的處理

編譯時遇見了段錯誤,

很多時候新手都會發現段錯誤,其實都是內存分配錯誤引起的:

即用定義指針直接賦值的,那麼char *p="aaa",其實和const char *p ="aaa";是一樣的,都在常量區,處於靜態存儲區,是隻讀的,不可修改的,"aaa",是固定存放在.rdata段的。如果對該只讀的進行操作,那麼系統就會提示“段錯誤”!

注意:上面的p是指針,在堆棧中,指向“aaa”這個固定的rdata,  *p是const類型,固定的,在.rdata只讀段,即"aaa"

1.如果使用char *p="aaa";那麼指針p 和aaa字符都在系統的只讀段,常量區,是不能修改的,readonly

    但是如果使用char p[]="aaa",那麼就可以修改,在讀寫段

2.上述的其實也就是靜態分配和動態分配的問題,如果定義 char *p;  //p是隻讀的,而 char p[];就不是隻讀,是可讀寫的.

然後char *p可以用p=malloc()來申請一塊動態的內存,free(p),那麼p的內容也是可以修改的

,然後用strcpy(p,"aaa");來拷貝進入。

 

導致段錯誤的常見編程有:
1。壞指針錯誤。例如在指針賦值之前就用它來引用內存;或向庫函數傳遞一個壞指針;

2。改寫錯誤.越過數組邊界寫入數據,在動態分配的內存兩端之外寫入數據;
p=malloc(4);p[-1]=0;
3.釋放引起的錯誤.釋放同一塊內存兩次,或釋放一塊未曾使用malloc分配的內存等等.

 

看下這個帖子:http://bbs.chinaunix.net/viewthread.php?tid=975562&extra=&page=1

http://iseeu.blog.51cto.com/178863/140610

使用舉例:

我定義一個結構體:

struct Test_SS{

             char username[16];                 //

              char *hostname;                     //

              struct other *baby;

}TT;

如果要初始化,那麼可以

strcpy(TT->username,""); //整個初始化                          千萬不能直接出現TT->username="aaa";   錯誤指針頭                                                                                            這麼能夠指向一串字符串

或者TT->username[0]='\0';給第一個字符初始化               

TT->baby=NULL;空指針

---------------------------(二)-------------------------------------

如果main函數要調用另外的一個包含指針的函數,例如

int Get(char * username,char *hostname,char* address,struct aaa * bbb);

那麼main函數中調用該函數,不能直接使用

Get(0,0,0,0);這種來初始化,必須要

定義在main函數中

char p1[11]={0};

char P2[11]={0};

char P3[11]={0};

struct aaa jiegou={0};

然後調用Get(p1,p2,p3,jiegou);這樣才行

不然運行程序就出現"段錯誤"

原因,因爲Get本身的指針是指向任何有效的內存段,如果直接放值,那麼系統是不允許的,保護內存的,因爲不知道該從哪裏找值。

指針必須指向有效的指針地址變量.

---------------------------(三)-------------------------------------

關於字符類的函數,strcpy...strncpy..strcat..以及memset..memcpy等引起的段錯誤:

例如main中定義一個指針,

        char *p;     然後如果使用strcpy(p,"aaaaa");

或是char pointer[10]="goodday";

       memcpy(p,pointer,sizeof pointer);來初始化它,都會引起段錯誤

 

原因是因爲char *p..只是定義了一個空指針p,該指針指向所有有效的內存,是一個臨時的不確定的地址,如果有內存保護機制的系統,編譯沒有問題,但是如linux下就會提示.運行“段錯誤”。

所以最好養成的習慣是:

1.。。經常使用的字符串用char p[];來定義,因爲這個定義下的p是一個固定的門牌號。

2.。。而結構體的定義,也是一樣,定義個固定的.......例如struct aaaa bbbbb;然後調用函數的時候,使用&bbbb來傳送。

3.要使用到的結構體最好都先定義一下.,不然很容易出現段錯誤。但是千萬不要用空指針類型來定義,

     如,struct *p;之類的。

 原文地址 http://blog.163.com/jk_new/blog/static/995485622009226104644352/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章