我释放分配的内存时出现munmap_chunk()错误

时间:2018-12-27 09:31:14

标签: c linux pointers malloc

我有一个全局的char* path,后来我调用了一个分配内存并返回它的函数,并且指向它的路径,当我释放它时出现此错误

唯一的方法是不释放指针

void free_memory() {

    if(path!=NULL)
        free(path);//problem

}

char* ExtractPath(char*str)
{
    char*temp=(char*)malloc(sizeof(char)*(strlen(str))+1);
    bzero(temp,strlen(temp));
    char ch ='/';

    if( checkUrl(str)==1) {
        if(strncasecmp(str,"http://",7)==0)
            str+=7;

        if(strstr(str,"/")!=NULL)
        {
            strcpy(temp,str);
            temp=strchr(temp,ch);
            strtok(temp,"\t");
        }
        else
            strcpy(temp,"/");
    }
    return temp;
}
path=ExtractPath(Users_input);//here the pointer points to the allocated memory that returned from the function the char*path is a global value

2 个答案:

答案 0 :(得分:1)

如我所见,问题出在

 bzero(temp,strlen(temp));

temp的内容不确定,将其传递给strlen()将会调用undefined behaviour

引用C11,第7.22.3.4章

  

malloc函数为对象的大小分配空间,该对象的大小由大小和   值不确定。

也就是说,对于free()部分的错误,您必须提供malloc()或家族返回的 exact 指针。

引用第7.22.3.3节

  

[...]否则,如果   该参数与内存管理器先前返回的指针不匹配   函数,或者如果通过调用free或realloc释放了空间,则   行为是不确定的。

在您的代码中,您实际上是通过说出

来修改存储在temp中的原始指针
        temp=strchr(temp,ch);
        strtok(temp,"\t");

并返回经过修改的temp

temp传递到free()将再次导致undefined behaviour

答案 1 :(得分:0)

由于ExtractPath不返回从malloc返回的值,因此无法释放返回的字符串。准确地将您从free获得的价值传递给malloc是合法的。

一旦您执行temp=strchr(temp,ch);,将从malloc返回的原始值丢失。从free返回的值上调用strchr是不合法的。

这是修复它的一种方法:

char* ExtractPath(char*str)
{
    char* temp=(char*)malloc(sizeof(char)*(strlen(str))+1);
    char* orig = temp; /* save the value we got back from malloc */
    char* ret;
    char ch ='/';

    if( checkUrl(str)==1) {
        if(strncasecmp(str,"http://",7)==0)
            str+=7;

        if(strstr(str,"/")!=NULL)
        {
            strcpy(temp,str);
            temp=strchr(temp,ch);
            strtok(temp,"\t");
        }
        else
            strcpy(temp,"/");
    }
    ret = malloc (strlen(temp) + 1);
    strcpy(ret, temp); /* make a new copy to return */
    free(orig); /* pass what malloc returned to free */
    return ret; /* caller can free this since we got it back from malloc */
}