簡體   English   中英

為函數中的指針賦值時的分段錯誤

[英]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 ,同時仍然保持z2char* (如果它是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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM