簡體   English   中英

strcpy給出分段錯誤

[英]strcpy giving segmentation fault

考慮以下代碼:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char *cexpGen();
char *chartoStr(char c);

char c_exp[] = "1";
char expressions[2] = {'+', '-'};

int main()
{
    cexpGen();
    printf("%s", c_exp);
    return 0;
}

char *cexpGen()
{
    int now = 1;
    while ((c_exp[strlen(c_exp) - 1]) > 10)
    {
        if ((c_exp[strlen(c_exp) - 1]) == '+' || (c_exp[strlen(c_exp) - 1]) == '-')
        {
            strcpy(c_exp, chartoStr(((c_exp[strlen(c_exp) - 2]) + 1)));
            continue;
        }

        if (now = 1)
        {
            strcpy(c_exp, chartoStr(expressions[0]));
            now++;
            cexpGen();
        }

        if (now = 2)
        {
            strcpy(c_exp, chartoStr(expressions[1]));
            now++;
            cexpGen();
        }

        if (now = 3)
        {
            strcpy(c_exp, chartoStr(((c_exp[strlen(c_exp) - 1]) + 1)));
        }
    }
}

char *chartoStr(char c)
{
    char s[2] = {c, '\0'};
    return s;
}

我想連接一個cahracter和一個字符串,但是我們沒有執行此操作的函數,所以我定義了一個chartoStr函數。 同樣,c_exp和表達式變量也不處於只讀模式,但是strcpy()給了我分段錯誤。 我也以任何方式嘗試了其他功能,例如strcat,但沒有幫助。

如果有幫助,我可以在VS Code中對其進行調試。 它打開strcpy-sse2-unaligned.S並在其中一行顯示分段錯誤。

是否需要launch.json或task.json文件? 我認為它們可能無濟於事,所以我沒有用代碼來補充問題,但請告訴我是否需要它們。

chartoStr()返回一個在函數末尾不再可用的本地,並由@kiran Biradar回答

char s[2] = {c, '\0'};
return s;  // bad, UB

調用chartoStr()一種替代方法,以使用復合文字 (在C99起)在調用代碼中創建字符串

// strcpy(c_exp, chartoStr(expressions[0]));
//            v-----------------------------v---- compound literal         
strcpy(c_exp, (char []){expressions[0], '\0'});

一個不錯的屬性是,沒有昂貴的分配,也沒有免費的指針。 復合文字在塊的末尾之前一直有效。


請注意,代碼可以通過在cexpGen() size_t len = strlen(c_exp)一次size_t len = strlen(c_exp)的長度並使用它來追加來進行其他改進。

// strcpy(c_exp, chartoStr(expressions[0]));
c_exp[len++] = expressions[0];
c_exp[len] = '\0';

其他問題

注意@alk關於char c_exp[] = "1";

while (c_exp[strlen(c_exp) - 1]) > 10未定義的行為strlen(c_exp)應該返回0。也許while ((len = strlen(c_exp)) > 0 && c_exp[len - 1]) > 10嗎?

if (now = 1)始終為true。 @ user3386109

因為您正在返回局部變量的地址,所以您遇到段錯誤。

char s[2] = {c, '\0'};
    return s;

一旦控件退出chartoStr函數, s將被銷毀。

編譯器也警告同樣

警告:函數返回本地變量[-Wreturn-local-addr]的地址

  return s; ^ 

您不需要strcpy復制可以直接分配的單個字符。

要解決您的問題,您可以嘗試以下操作。

char *chartoStr(char c)
{
    char *s = malloc(2);
     s[0] = c;
     s[1] =  '\0';
    return s;
}

不要忘記釋放s工作完成之后。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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