【问题标题】:Returning pointer freed inside function返回函数内部释放的指针
【发布时间】:2013-10-20 15:53:33
【问题描述】:

似乎运行没有任何问题,但我在想,当它返回时,buff 可能会自动被释放,这反过来又会释放 *string 并在下次引起问题我分配并且该内存被覆盖(或更糟,等等)。我不想通过反复试验进行测试,因为到目前为止我的测试可能很幸运。我做错了吗?

void strCat1000(char *concatDest, char *format, ...)
{
  char buff[1000];

  va_list arg_ptr;
  va_start(arg_ptr, format);

  vsnprintf(buff, sizeof(buff), format, arg_ptr);

  va_end(arg_ptr);

  free(concatDest);
  concatDest=buff;
}

更简洁的说,concatDest 是指向这个函数返回后释放的内存吗?

【问题讨论】:

  • 创造者应该是毁灭者。考虑concatDest 是否在堆栈上?!
  • 哎呀 - 听起来有点宗教 - 并不意味着它是那样的
  • 这段代码应该做什么?
  • 它应该连接几个字符串并将它们放在concatDest中。我想这样做,所以如果我想将结果存储在我正在连接的字符串之一中,它仍然可以工作。
  • 总之...这个函数是个灾难,最好将它声明为char* strCat1000(char *format, ...),并且不要在里面做任何释放。

标签: c pointers gcc


【解决方案1】:
concatDest=buff;
}

最后一条语句不会改变程序的可观察行为,并且很可能会被任何体面的编译器优化。

记住 C 是按值传递参数的,你修改的不是原始指针,而是函数中的本地副本。

【讨论】:

  • @AppFzx 如果你想修改原来的指针是的,但是你不能通过bufferbuffer对象具有自动存储时长,在函数返回时销毁。
  • 并称它为strCat1000(&logText, "log this %s, %s, %s","stuff1","stuff2","stuff3")
  • @AppFzx 是的,但是再次返回 buff 是错误的,因为它将被销毁。此外,您在函数中的free 设计不好,最好在与malloc 相同的范围内free
【解决方案2】:
concatDest=buff;

这不是一个好主意,因为当函数返回时,它的所有 local variables are destroyed。因此,如果您尝试访问存储在buff 中的数据(在此函数之外),其地址已分配给concatDest,您将出现Segmentationf 错误

【讨论】:

    【解决方案3】:

    你应该是,

    • 采用长度参数
    • 将 concatDest 传递给 vsnprintf

    ..但是你只剩下 snprintf

    buff 是在堆栈上分配的,并且将 concatDest 分配给它的地址将不起作用,因为它指向的内存会在堆栈弹出(当您返回时)消失。

    更简洁:是的,内存已被释放。它可能没有被覆盖(所以它可能会工作一点点),但很快就会被覆盖。

    【讨论】:

      【解决方案4】:

      buff是局部变量,所以函数返回时无效(出栈)。但是concatDest 也是如此,所以没有问题——你只有一个指向局部变量的局部变量,并且两者同时消失。

      现在你可能会想到如果你这样调用这个函数:

      strCat1000(string, "some format", some other args);
      

      但是在这种情况下,string 不受函数中concatDest 更改的影响——参数在 C 中按值传递。当然,这意味着你的函数没有效果 根本 - 它打印到临时缓冲区然后销毁该缓冲区,但它对 string*string 正在处理中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-08-07
        • 2022-01-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-14
        • 2011-08-28
        • 1970-01-01
        相关资源
        最近更新 更多