【问题标题】:Free memory in another function在另一个函数中释放内存
【发布时间】:2018-02-07 09:39:08
【问题描述】:

所以我有这段代码,其中分配发生在一个函数中,而解除分配正在调用函数中完成。尝试通过 ptr 或 *ptr 释放内存时收到分段错误或 Abort 消息。请看:

#include <stdio.h>

int main()
{

    char *ptr;
    fun(&ptr);
    printf("ptr = %p\n",ptr);
    printf("&ptr = %p\n",&ptr);
    printf("String ptr = %s\n",ptr);
    free (ptr);

    return 0;
}
void fun(char **str)
{
    *str = malloc(10);
    *str = "HELLO";
    printf("str = %p\n",str);
    printf("&str = %p\n",&str);

    printf("String str = %s\n",*str);
}

以下是输出:

str = 0x7ffe63247858                                                                                                                 
&str = 0x7ffe63247838                                                                                                                
String str = HELLO                                                                                                                   
ptr = 0x400764                                                                                                                       
&ptr = 0x7ffe63247858                                                                                                                
String ptr = HELLO                                                                                                                   
*** Error in `/home/a.out': munmap_chunk(): invalid pointer: 0x0000000000400764 ***                                                  
Aborted  

问题:

为什么我们不能释放 ptr ?如果可以,最好的方法是什么?

【问题讨论】:

  • @ThiruShetty 实际上这不是问题(见答案)

标签: c malloc


【解决方案1】:

您正在覆盖后面行中的指针值,使*str 指向一个文字。

所以你有一个内存泄漏通过尝试free 一个文字未定义的行为。

你可能是说

strcpy(*str,"hello");

请注意,这 2 行可以像这样更改为单行:

*str = strdup("HELLO");

它的优点是为字符串分配确切的字节数而不是猜测。

【讨论】:

  • 非常感谢您的说明。使用 strdup() 将使任务更容易。但是应该有一些其他的方法来做到这一点,而不使用 strcpy() 或 strdup()。比如,如果我们无法访问字符串函数。知道如何实现这一目标吗?
  • 是的,但这有点可笑,因为如果您无权访问字符串函数,您可能也无权访问malloc。我会计算字符串中有多少个字符,加 1,malloc 适当的大小,然后逐字节复制。除非有一个可以调用 malloc 但不是 strcpy 的真实设置,否则不要编辑答案
  • 几年前也有关于使用strdup或不使用的争论,但现在strdup已成为标准。
【解决方案2】:

当您执行*str = "HELLO"; 时,它不会产生您期望的效果。您不是为分配的内存分配值,而是重新分配指针以指向字符串文字,因此稍后您尝试释放它(因此出现错误)。而不是这个,你应该使用strcpy,比如strcpy(*str, "HELLO")

【讨论】:

    【解决方案3】:

    回答如何在不显式复制字符串的情况下执行此操作的问题,而不是

    char *p = "hello";
    

    char p[] = "hello";
    

    第一个点 p 指向内存的不可修改部分。第二个分配一个足够大的数组来保存文字并将文字复制到其中。

    【讨论】:

      【解决方案4】:

      你在有趣的 malloc 之后更改内存地址指向的 str 指针。你应该做 strcpy 而不是直接赋值:

      #include <stdio.h>
      
      int main()
      {
      
          char *ptr;
          fun(&ptr);
          printf("ptr = %p\n",ptr);
          printf("&ptr = %p\n",&ptr);
          printf("String ptr = %s\n",ptr);
          free (ptr);
      
          return 0;
      }
      void fun(char **str)
      {
          *str = malloc(10);
          strcpy(*str,"HELLO");//*str = "HELLO";
          printf("str = %p\n",str);
          printf("&str = %p\n",&str);
      
          printf("String str = %s\n",*str);
      }
      

      【讨论】:

        猜你喜欢
        • 2012-07-31
        • 2017-04-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-03
        相关资源
        最近更新 更多