简体   繁体   English

strsep() 导致分段错误

[英]strsep() causing Segmentation fault

I am having a problem with my program in which I am getting a segmentation fault from strsep() which was gotten from GDB and has the error message我的程序有问题,我从 GDB 获取的strsep()收到分段错误,并显示错误消息

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

My code is as follows:我的代码如下:

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;
}

Any help would be greatly appreciated as I have spent hours trying to solve this problem任何帮助将不胜感激,因为我花了几个小时试图解决这个问题

The arguments for the function are ("Hello World", "@", "&")函数的参数是("Hello World", "@", "&")

EDIT编辑

So I have managed to get rid of the segment fault by changing the code to所以我设法通过将代码更改为

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;
}

However now I have a new problem with commands returning a null array where every index is out of bounds.但是现在我有一个新问题,命令返回一个空数组,其中每个索引都超出范围。

EDIT 2编辑 2

I should also clarify on what I am trying to do a bit so essentially commands is of type char* commands[100] and I want to pass it into the function when then modifies the original pointer array and store say `"Hello World"' into commands[0] then I want to modify this value outside the function.我还应该澄清一下我想要做的事情,所以基本上命令是char* commands[100] ,我想在修改原始指针数组时将它传递给函数并存储说“Hello World”进入命令 [0] 然后我想在函数外修改这个值。

Your usage of commands is inconsistent with the function prototype: the caller passes an array of 100 char* , commands should be a pointer to an array of char * , hence a type char **commands or char *commands[] .您对commands使用与函数原型不一致:调用者传递 100 个char*的数组, commands应该是指向char *数组的指针,因此类型为char **commandschar *commands[] For the caller to determine the number of tokens stored into the array, you should either store a NULL pointer at the end or return this number or both.为了让调用者确定存储在数组中的标记数,您应该在末尾存储一个NULL指针或返回此数字或两者兼而有之。

Storing commands[i] = strsep(...) is incorrect as commands is defined as a char * , not a char ** .存储commands[i] = strsep(...)是不正确的,因为commands被定义为char * ,而不是char **

It is surprising you get a segmentation fault in strsep() because the arguments seem correct, unless character happens to be an invalid pointer.令人惊讶的是,您在strsep()strsep()分段错误,因为参数似乎是正确的,除非character恰好是无效指针。

Conversely you have undefined behavior most likely resulting in a segmentation fault in strcasecmp(commands[i], "") as commands[i] is a char value, not a valid pointer.相反,您有未定义的行为很可能导致strcasecmp(commands[i], "")中的分段错误,因为commands[i]是一个char值,而不是一个有效的指针。

Here is a modified version:这是一个修改后的版本:

// 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;
}

The memory allocated for the tokens can be freed by freeing the first pointer in the commands array.可以通过释放commands数组中的第一个指针来释放为令牌分配的内存。 It might be simpler to duplicate these tokens so they an be freed in a more generic way.复制这些令牌可能更简单,以便以更通用的方式释放它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM