Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C中拆分字符串时出现内存泄漏问题_C - Fatal编程技术网

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

在C中拆分字符串时出现内存泄漏问题,c,C,我正在尝试根据以下规则拆分字符串: 不带“”的单词应视为单独的字符串 任何包含“”的内容都应视为一个字符串 然而,当我在valgrind中运行它时,我会得到无效的空闲和无效的读取大小错误,但是如果我删除这两个空闲,我会得到内存泄漏。如果有人能给我指出正确的方向,我将不胜感激 调用split_字符串的代码 char *param[5]; for(i = 0;i < 5;i++) { param[i] = NULL; } char* us

我正在尝试根据以下规则拆分字符串:

  • 不带“”的单词应视为单独的字符串
  • 任何包含“”的内容都应视为一个字符串
  • 然而,当我在valgrind中运行它时,我会得到无效的空闲和无效的读取大小错误,但是如果我删除这两个空闲,我会得到内存泄漏。如果有人能给我指出正确的方向,我将不胜感激

    调用split_字符串的代码

        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);
    
    char*param[5];
    对于(i=0;i<5;i++){
    参数[i]=NULL;
    }
    char*user=getenv(“LOGNAME”);
    char-tid[9];
    char*instring=(char*)malloc(201);
    /
    而((printf(“%s%s>”,用户,gettime(tid))&&(instring)
    =fgets(指令,201,标准输入))!=NULL){
    int paramsize=拆分字符串(param,instring);
    

    试图释放参数的代码

                    for(i = 0;i < 5;i++) {
                    if(param[i] != NULL) {
                        free(param[i]);
                        fprintf(stderr,"%d",i);
                    }
                }
    
    (i=0;i<5;i++)的
    {
    if(参数[i]!=NULL){
    自由(参数[i]);
    fprintf(标准,“%d”,i);
    }
    }
    

    int分割字符串(字符**参数,字符*字符串){
    int paramplace=0;//hvor vi er i param
    int tempplace=0;//hvor i temp vi er
    char*temp=malloc(201);
    int命令=0;
    int消息=0;
    对于(;(*string!='\0')&&(*string!=10)&¶mplace<4;string++){
    如果((*字符串=='')和(&(消息==0)){
    如果(命令==1){
    临时[tempplace]='\0';
    param[paramplace++]=temp;
    tempplace=0;
    命令=0;
    }
    }
    否则{
    如果(*字符串==“”){
    如果(消息==0)消息=1;
    else消息=0;
    }
    如果(命令==0){
    免费(临时);
    温度=malloc(201);
    }
    命令=1;
    如果(*字符串!=“”){
    temp[tempplace++]=*字符串;
    }
    }
    }
    如果(命令==1){
    临时[tempplace]='\0';
    param[paramplace++]=temp;
    }
    param[paramplace]=NULL;
    免费(临时);
    返回目的地;
    }
    
    也许你没有删除正确的free()?实际问题可能在调用split_字符串的代码中。你能显示它吗?

    也许你没有删除正确的free()?实际问题可能在调用split_字符串的代码中。你能显示它吗?

    当你释放临时缓冲区时,你也会释放参数[]缓冲区,存储令牌的地方。另一方面,如果您不调用不应该调用的
    free(temp)
    ,则函数调用方有责任在不需要令牌时调用
    free(param[n])

    当您释放临时缓冲区时,您也会释放param[]缓冲区,存储令牌的地方。另一方面,如果您不调用
    free(temp)
    ,而您不应该调用,则函数调用方将负责调用
    free(param[n])
    ,当不需要令牌时。

    据我所知,您希望将拆分的字符串作为指针数组放入
    param
    中(可能使调用方负责释放它们)。在循环中if语句的第一个分支中,可以通过将当前的
    temp
    缓冲区分配给该位置来完成。但是,一旦启动新字符串(当
    comnand==0
    时),就释放了该空间,从而使以前的
    param
    条目指针无效


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

    据我所知,您希望将拆分的字符串作为指针数组放入
    param
    (可能是调用方负责释放它们)。在循环中if语句的第一个分支中,可以通过将当前的
    temp
    缓冲区分配给该位置来完成。但是,一旦启动新字符串(当
    comnand==0
    时),就释放了该空间,从而使以前的
    param
    条目指针无效


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

    很难理解您的代码。我建议您改用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();
    }
    

    未经测试。

    很难理解您的代码。我建议您改用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();
    }
    

    未经测试。:

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

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

    这有点脱节,但我会尝试获取相关部分这有点脱节,但我会尝试获取相关部分我有一个函数可以做到这一点,我有一个函数可以做到这一点,我有一个函数可以做到这一点,我有一个函数可以做到这一点,我有一个函数可以做到这一点,我有一个函数可以做到这一点,我有一个函数可以做到这一点,我有一个函数可以做到,我有一个函数可以做到这一点,我会记住这一点,如果我没有时间重写代码:)谢谢,我会记住这一点,如果我没有时间重写代码:)