在C中拆分字符串时出现内存泄漏问题

时间:2010-11-15 15:15:32

标签: c

我试图按照以下规则拆分字符串:

  1. 周围没有“”的单词应视为单独的字符串
  2. 周围的任何东西应被视为一个字符串
  3. 然而,当我在valgrind中运行它时,我得到了无效的释放和无效的读取大小错误,但如果我删除了两个释放,我会得到内存泄漏。如果有人能指出我正确的方向我会很感激

    调用split_string

    的代码
        char *param[5];
        for(i = 0;i < 5;i++) {
                param[i] = NULL;
        }
        char* user = getenv("LOGNAME");
        char tid[9];
        char* instring = (char*) malloc(201);
    
        /
        while((printf("%s %s >",user,gettime(tid)))&&(instring
                =fgets(instring,201,stdin)) != NULL) {
                int paramsize = split_string(param, instring);
    

    尝试释放param的代码

                    for(i = 0;i < 5;i++) {
                    if(param[i] != NULL) {
                        free(param[i]);
                        fprintf(stderr,"%d",i);
                    }
                }
    

        int split_string(char** param, char* string) {
        int paramplace = 0; //hvor vi er i param
        int tempplace = 0; //hvor i temp vi er
    
        char* temp = malloc(201); 
        int command = 0; 
        int message = 0; 
        for(; (*string != '\0') && (*string != 10) && paramplace < 4; string++) {
                if((*string == ' ') && (message == 0)) {
                        if(command == 1) {
                            temp[tempplace] = '\0'; 
                            param[paramplace++] = temp; 
                            tempplace = 0;
                            command = 0;
                        }
                }
                else {
                        if(*string =='"') {
                                if(message == 0) message = 1;
                                else message = 0;
                        }
                        if(command == 0) {
                                free(temp);
                                temp = malloc(201);
                        }
                        command = 1;
                        if(*string != '"') {
                                temp[tempplace++] = *string;
                        }
                }
        }
        if(command == 1) {
                temp[tempplace] = '\0';
                param[paramplace++] = temp;
        }
        param[paramplace] = NULL;
        free(temp);
        return paramplace;
    }
    

5 个答案:

答案 0 :(得分:2)

据我所知,你想把分裂字符串放入param作为一个指针数组(大概是让调用者负责释放它们)。在循环中if语句的第一个分支中,可以通过将当前temp缓冲区分配给该位置来实现。但是,一旦你开始一个新字符串(当comnmand == 0时,你释放该空间,使前一个param条目指针无效。

只释放每个指针一次。我不排除此代码中的其他泄漏:我认为您可以简化您的状态机(并可能因此找到其他错误)。

答案 1 :(得分:1)

释放临时缓冲区时,还可以释放存储令牌的param []缓冲区。另一方面,如果你不打电话给free(temp),你不应该打电话给你free(param[n]),当你不需要令牌时,你可以打电话给{{1}}。

答案 2 :(得分:0)

也许你没有删除正确的免费()?实际问题可能在调用split_string的代码中。你能表现出来吗?

答案 3 :(得分:0)

很难理解你的代码。我建议你改用sscanf。

您可以使用如下格式字符串:

"\"%[^\"]\"%n"

了解它的作用。

我写了一个例子:

if( sscanf( string, "\"%[^\"]\"%n", matchedstring, &bytesread ) )
{
    handlestring( matchedstring );
    string += bytesread;
}
else if( sscanf( string, "%s%n", matchedstring, &bytesread ) )
{
    handlestring( matchedstring );
    string += bytesread;
}
else
{
    handleexception();
}

未测试。 :)

答案 4 :(得分:0)

感谢所有评论,我找到了答案。 问题是for循环之前的第一个malloc是多余的,因为在它开始将temp放入param之前会有另一个malloc,因此没有指向第一个malloc的指针,所以它只是丢失了。