C中奇怪的malloc错误,标记单词

时间:2012-07-04 00:29:52

标签: c malloc

我试图用空格和引号来标记一个单词,但是在输出正确后我得到了一个奇怪的malloc错误。

我希望这个函数接受类似的东西:

hello world "SOme quote"

,输出应为:

hello
world
"some quote"

或输入是:

hello world no quote 

输出应为:

hello
world
no
quote

<击> 但是现在,我得到了:

Hello
WOrld
"Hello World"
*** glibc detected *** ./a.out: free(): invalid next size (fast): 0x0000000001760010 ***
a.out: malloc.c:2451: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed.
Aborted (core dumped)

看起来输出是正确的,但是在

后它会变得混乱

代码是:

int process_command(char command[80]){
char curr_char;
char *word;
int start_pos;
int i;
int len;
len = strlen(command);
for(i=0,start_pos=0;i<strlen(command);i++){
    curr_char = command[i];
    if (curr_char == ' '){
        if (command[i-1]==' ') {start_pos++;continue;}
        word = malloc(i-start_pos*(sizeof(char)));
        strncpy(word,command+start_pos,i-start_pos);
        printf("%s\n",word);
        free(word);

        start_pos =i+1;

    }
    else if (curr_char == '\"'){
        word= malloc(len-i*(sizeof(char)));
        strncpy(word,command+i,len);
        printf("%s\n",word);
        free(word);
        i=len+len;
    }

}

return 0;
}
int main(){
    char buffer[80] = "Hello   WOrld  \"Hello World\"";
    process_command(buffer);
    return 0;
}

<击>

问题得到解决!谢谢 下面是更新后的代码:

int process_command(char command[80]){
char curr_char;
char *word;
int start_pos;
int i;
int len;
int quote=0;
len = strlen(command);
for(i=0,start_pos=0;i<strlen(command);i++){
    curr_char = command[i];
    if (curr_char == ' '){      /*If there was a space found copy the stuff before the space*/
        if ( i>0 && command[i-1]==' ') {
            start_pos++;
            continue;
        }
        word = malloc(i-start_pos+1*(sizeof(char)));
        strncpy(word,command+start_pos,i-start_pos);
        word[i-start_pos+1]='\0';
        printf("%s\n",word);
        free(word);
        start_pos =i+1;

    }
    else if (curr_char == '\"'){        /*If a quote was found, copy the rest of the string and exit loop*/
        word= malloc(len-i+1*(sizeof(char)));
        strncpy(word,command+i,len-i);
        word[len-i+1]='\0';
        printf("%s\n",word);
        free(word);
        quote=1;
        break;
    }

}if (quote==0){                 /*If there was no quote in the string, get the last element*/
    word = malloc(len-start_pos+1*(sizeof (char)));
    strncpy(word,command+start_pos,len-start_pos);
    word[len-start_pos+1]='\0';
    printf("%s\n",word);
        free (word);
    }
    return 0;
}
int main(){
    char buffer[80] = "Hello   \"WOrld  test\"";
    process_command(buffer);
    return 0;
}

但是,我想知道这是否是一种有效的标记方式? 这是处理用户键入的指令。因此,如果用户输入

add 1 2 "SOme text"

我想将查询标记为三个部分然后进行处理。所以要做到这一点,我正在对它进行标记,并将它们推入队列,以后我可以逐个弹出项目并处理它。

2 个答案:

答案 0 :(得分:1)

你必须确保为你要做的strncpy分配足够的内存。 这两行是一对一的,因为strncpy也写了一个零字节:

word = malloc(i-start_pos*(sizeof(char)));
strncpy(word,command+start_pos,i-start_pos);

这两行没有意义:你分配len-i字节,然后写len字节(加上零字节)给它:

word = malloc(len-i*(sizeof(char)));
strncpy(word,command+i,len);

答案 1 :(得分:1)

您有几个问题,其中一些是:

for(i=0,start_pos=0;i<strlen(command);i++){
    curr_char = command[i];
    if (curr_char == ' '){
        if (command[i-1]==' ') {start_pos++;continue;}      // accesses an invalid array offset when i == 0
        word = malloc(i-start_pos*(sizeof(char)));          // doesn't allocate space for null terminator
        strncpy(word,command+start_pos,i-start_pos);        // doesn't null terminate the string
        printf("%s\n",word);
        free(word);

        start_pos =i+1;

    }
    else if (curr_char == '\"'){
        word= malloc(len-i*(sizeof(char)));                 // doesn't allocate space for null terminator
        strncpy(word,command+i,len);                        // writes past the end of the allocated buffer
        printf("%s\n",word);
        free(word);
        i=len+len;                                          // not sure what the intent of this is?  use `break;`?
    }

}

一般来说,strncpy()应该避免,因为它并不总是按用户的意料行事,所以它经常涉及错误的代码。

此外,您的报价处理非常简单 - 它假定引用的项始终是字符串中的最后一个标记。这可能是你想要的,但它不适用于一组令牌,如:

"one and two" three