[英]Segmentation fault when assigning values to pointers in function
長時間聽眾,第一次來電。
如果這個問題已經得到解決,我會道歉(我想這已經被廣泛報道),但我已經搜索了很多關於指針和其他看似相關主題的問題,但我仍然無法解決我的問題。
我正在為類項目編寫一個字符串庫,當我嘗試這個時遇到分段錯誤錯誤:
#include "str2107.h"
#include <stdio.h>
void lstrip(char *s) {
char *p, *q;
p = q = s;
while (*p == ' ' && *p != '\0') {
*p++;
}
while (*p != '\0') {
*q = *p; //this is where the actual segmentation fault occurs.
p++;
q++;
}
*q = '\0';
}
我的主程序看起來像這樣:
#include <stdio.h>
#include <stdlib.h>
#include "str2107.h"
int main(int argc, char** argv) {
char *z1 = " weeee";
printf("lstrip function\n");
printf("%s\n",z1);
lstrip(z1);
printf("%s\n",z1);
return 0;
}
z1
指向字符串文字 ,修改字符串文字是未定義的行為 。 或者你可以使用z1
的以下聲明,它可以修改:
char z1[] = " weeee";
如果我們看看C99標准草案第6.4.5
節字符串文字第6段說( 強調我的 ):
如果這些數組的元素具有適當的值,則這些數組是否不同是未指定的。 如果程序試圖修改此類數組,則行為未定義。
還有一些其他觀點,如WhozCraig指出這一行:
while (*p == ' ' && *p != '\0') {
可以更簡潔地寫成:
while (*p == ' ' ) {
你也在這里使用間接 :
*p++;
但實際上並沒有使用結果值,因此您可以將其更改為:
p++;
當你寫char *z1 = " weeee";
然后z1
是指向 代碼部分中的內存的指針 ,因此您無法更改它。
如果你改變它char z1[] = " weeee";
然后z1
是堆棧上的字符數組,您可以更改它。
如果你寫過char const *z1 = "...";
那么這將是一個編譯錯誤 ,它比分段錯誤更好,更可取。
char *z1 = " weeee";
應該
const char *z1 = " weeee";
因為字符串文字是不變的。 嘗試類似的東西:
const char *z1 = " weeee";
char *z2 = strdup(z1);
lstrip(z2);
在一個可變字符串上調用lstrip
,同時仍然保持z2
為char*
(如果它是char[]
不是你想要的)。
正如很多其他人已經向你指出的那樣,當你寫道:
char *whatever = "some value";
這與以下內容大不相同:
char *whatever = malloc(length("some value") + 1); strcpy(whatever, "some value");
不同之處在於某些文字(即在編譯時定義的字符串)可以是常量,但我不知道是否總是或要求它是常量。 由於不應修改常量,並且在字符串中放置'\\ 0'字符,這會導致分段錯誤。
這可能有很多原因,但我所知道的簡單方法是,如果程序知道每次使用相同的字符串都可以安全地重用,那么該程序可以進行優化。
舉個例子:
char *whatever1 = malloc(length("some value") + 1); strcpy(whatever1, "some value"); char *whatever2 = malloc(length("some value") + 1); strcpy(whatever2, "some value"); if(whatever1 == whatever2) { printf("This should never happen!\n"); } if("some value" == "some value") { printf("A good compiler should always do this!\n"); }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.