【问题标题】:C alternative to mallocmalloc 的 C 替代品
【发布时间】:2016-10-09 15:35:16
【问题描述】:

在阅读 K&R(第 6.5 节,第二版)时,我遇到了以下功能:

struct tnode *talloc(void)
{
    return (struct tnode *) malloc( sizeof(struct tnode) );
}

该函数分配一些空间来存储结构 tnode。我只是想通过询问我是否会达到同样的效果来检查我的理解:

struct tnode *talloc(void)
{
    struct tnode s;
    return &s;
}

【问题讨论】:

  • 第二个代码片段将不起作用,因为它正在返回一个指向本地堆栈上的项目的指针。本地堆栈在超出范围时变为未定义,就像函数退出时一样。

标签: c pointers struct malloc


【解决方案1】:

答案是否定的。

struct tnode *talloc(void)
{
    return (strcut tnode *) malloc( sizeof(strcut tnode) );
}

malloc 分配空间供以后使用,通常空间分配在heap 上。当您不再需要它时,需要手动释放使用malloc 分配的空间 - 否则会出现内存泄漏。该指针可以在函数返回后使用。

在下面的例子中

strcut tnode *talloc(void)
{
    struct tnode s;
    return &s;
}

结构在stack 上分配,并在函数退出时自动释放。因此,您返回的指针成为您无法使用的悬空指针(在函数之外)。在其作用域之外使用作用域对象是undefined behavior

【讨论】:

  • 一个后续问题:在第二个示例中,返回的指针是指向 NULL 还是指向内存中某个不可预测的位置?
  • 指针将指向栈上结构体的地址(!=NULL)。
  • 但是在这个地址下就卡住了会有一些不是我在函数里面声明的东西吧?
  • @SergeyZykov 可能有也可能没有,因为从该函数返回后,返回地址下的内存将未定义。无论如何这样做都是错误的。
  • IIRC 返回的指针值将是“不确定的”,即即使查看也不安全,更不用说取消引用了。从技术上讲,它不必是“地址”。
【解决方案2】:

当代码调用malloc 时,系统会给出一个指向内存区域的指针,系统承诺不会将其用于任何其他目的,直到该指针传递给free 或@987654323 @。在您的第二个示例中,声明保留了足够大的存储区域以容纳struct tnode,并保证在执行离开块(*)之前不会重用存储。一旦执行离开块,用于保存struct tnode 的存储将有资格被重新用于其他目的

(*) 如果这样做不会对程序行为产生明显影响,则实现可能会将存储用于其他目的,但程序员通常不必担心这一点。

【讨论】:

    猜你喜欢
    • 2012-10-30
    • 2010-12-10
    • 2013-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多