簡體   English   中英

strsep() 導致分段錯誤

[英]strsep() causing Segmentation fault

我的程序有問題,我從 GDB 獲取的strsep()收到分段錯誤,並顯示錯誤消息

Program received signal SIGSEGV, Segmentation fault.
0x00002aaaaad64550 in strsep () from /lib64/libc.so.6

我的代碼如下:

int split(char *string, char *commands, char *character) {
    char **sp = &string;
    char *temp;
    temp = strdup(string);
    sp = &temp;
    for (int i = 0; i < 100; i++) {
        commands[i] = strsep(sp, character);
        if (commands[i] == '\0') {
            return 0;
        }
        if (strcasecmp(commands[i], "") == 0) {
            i--;
        }
        printf("%d", i);
    }
    return 0;
}

任何幫助將不勝感激,因為我花了幾個小時試圖解決這個問題

函數的參數是("Hello World", "@", "&")

編輯

所以我設法通過將代碼更改為

int split(char* string, char* commands, char* character) {
        for(int i = 0; i < 100; i++) {
                commands[i] = strsep(&string, character);
                if(commands[i] == '\0') {
                        return 0;
                }
                if(strcasecmp(&commands[i], "") == 0) {
                        i--;
                }
        }
        return 0;
}

但是現在我有一個新問題,命令返回一個空數組,其中每個索引都超出范圍。

編輯 2

我還應該澄清一下我想要做的事情,所以基本上命令是char* commands[100] ,我想在修改原始指針數組時將它傳遞給函數並存儲說“Hello World”進入命令 [0] 然后我想在函數外修改這個值。

您對commands使用與函數原型不一致:調用者傳遞 100 個char*的數組, commands應該是指向char *數組的指針,因此類型為char **commandschar *commands[] 為了讓調用者確定存儲在數組中的標記數,您應該在末尾存儲一個NULL指針或返回此數字或兩者兼而有之。

存儲commands[i] = strsep(...)是不正確的,因為commands被定義為char * ,而不是char **

令人驚訝的是,您在strsep()strsep()分段錯誤,因為參數似乎是正確的,除非character恰好是無效指針。

相反,您有未定義的行為很可能導致strcasecmp(commands[i], "")中的分段錯誤,因為commands[i]是一個char值,而不是一個有效的指針。

這是一個修改后的版本:

// commands is assumed to point to an array of at least 100 pointers
// return the number of tokens or -1 is case of allocation failure
int split(const char *string, char *commands[], const char *separators) {
    char *dup = strdup(string + strcspn(string, separators));
    if (temp == NULL)
        return -1;
    char *temp = dup;
    char **sp = &temp;
    int i = 0;
    while (i < 99) {
        char *token = strsep(sp, separators);
        if (token == NULL) // no more tokens
            break;
        if (*token == '\0') // ignore empty tokens
            continue;
        commands[i++] = token;
    }
    commands[i] = NULL;
    if (i == 0) {
        free(dup);
    }
    return i;
}

可以通過釋放commands數組中的第一個指針來釋放為令牌分配的內存。 復制這些令牌可能更簡單,以便以更通用的方式釋放它們。

暫無
暫無

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

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