天天看點

段錯誤 php,段錯誤

---------------------------(一)-------------------------------------

編譯時遇見了段錯誤,

很多時候新手都會發現段錯誤,其實都是記憶體配置設定錯誤引起的:

即用定義指針直接指派的,那麼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

使用舉例:

我定義一個結構體:

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;之類的。