編譯時遇見了段錯誤, 很多時候新手都會發現段錯誤,其實都是內存分配錯誤引起的: 即用定義指針直接賦值的,那麼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");來拷貝進入。
導致段錯誤的常見編程有:
2。改寫錯誤.越過數組邊界寫入數據,在動態分配的內存兩端之外寫入數據;
看下這個帖子: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/