使用释放的内存是否有风险?

时间:2012-11-20 21:21:27

标签: c memory-management

假设我有一个char指针指向内存中的某个字符串 并假设我想将该字符串复制到内存中的其他位置。

void cpy(char **dst, char *src)
{
    *dst = (char *) realloc(*dst, strlen(src) + 1);
    memcpy(*dst, src, strlen(src) + 1);
}

(假设内存分配成功,src不为NULL)
如果我这样称呼这个函数怎么办:

char *str = malloc(14);
memcpy(str,"hello, world!", 14);
cpy(&str,str+7);

现在我希望srt指向字符串"world!"(在我的测试中它会发生)。
但令我担忧的是,在cpy的来电中,*dstsrc实际指向相同字符串的不同位置。并且,在realloc上调用*dst时,可能会释放此内存。但在接下来的一行中,我试图用memcpy从那个地方复制。

所以问题是:它有什么问题吗? 或者用另一种方式 - 是否可以释放记忆,然后立即使用它?

感谢。

注意:示例已更新,以便在使用realloc获取的内存上调用malloc

2 个答案:

答案 0 :(得分:9)

这一切都有问题。在realloc等未获得的指针上调用malloc是彻头彻尾的未定义行为

正如@Daniel Fischer指出的那样,在重叠的内存区域使用memcpy也是未定义的行为(在这种情况下你应该使用memmove),所以你必须小心。


更新:经过实质性修改后,问题就完全不同了。它现在相当于这个压缩版本:

char * s = malloc(14);
strcpy(s, "hello, world!");

char * p = realloc(s, 14);

memcpy(p, s, 14);

这也是未定义的行为,因为在成功s之后不允许再访问realloc指向的内存,并且不允许您访问p指向的内存。 {1}} realloc失败后的{1}}。

答案 1 :(得分:1)

您的示例中的隐含假设是允许cpy释放它未分配的内存。这是一种狡猾的假设,但只要它是有意的,那就没关系。在这种情况下,请分别使用mallocfree而不是realloc

void cpy(char **dst, char *src)
{
    // obtain completely new memory (realloc might do this anyway)
    char* new = malloc(strlen(src) + 1);

    // duplicate the string
    memcpy(new, src, strlen(src) + 1);

    // release the original memory now that we know we are done with it
    free(*dst);

    // indicate where to find the new string
    *dst = new;
}

这仍然不是一个好主意,因为没有办法知道其他变量可能指向你free的内存,但是如果你有办法做出这样的保证,这个是你需要的代码类型。