【问题标题】:Use an un-initialized pointer as a function parameter使用未初始化的指针作为函数参数
【发布时间】:2011-05-05 10:16:17
【问题描述】:

当我想将未初始化的指针传递给函数时,它会出现运行时错误。 但是如果我将此指针作为参考传递,它就可以正常工作。我无法解释为什么...

class Body
{

};

void check(Body* b)
{
    b = new Body();
}

void checkRef(Body* &b)
{
    b = new Body();
}

int main001()
{
    Body* b;

    //check(b);// error: The variable 'b' is being used without being initialized. (in VS2010)
    checkRef(b); // OK


    return 0;
}

b 传递给 check 和 checkRef 有什么区别?我在 VisualStudio2010 中遇到运行时错误。错误:正在使用变量“b”而未初始化。

编辑:这是一个 VS2010 调试输出。发布版本中没有出现“错误”

【问题讨论】:

  • 你确定第一个给你的是 runtime 错误,而不是 compile-time 错误吗?您收到的错误消息是什么?
  • 如果 check() 返回指针,你的生活会轻松很多。
  • 我确定。在VS2010中,@“变量'b'正在被使用而没有被初始化。”
  • 我认为它不应该给出任何运行时错误。 check results in a memory leak but should not be runtime error。区别在于 CheckRef 将导致内存分配,其指针将在 main 中使用 b。在其他情况下,当 check 返回时,b 仍然是悬空的。
  • @demaxSH:几乎可以肯定不是运行时错误,尽管它可能是从您的调试器中输出的。一个小屏幕截图可以解决这个问题,但这并不重要。

标签: c++ pointers pass-by-reference


【解决方案1】:

Body* b 没有设置 b 指向任何合理的东西。所以它可能指向某个随机位置,可能会导致地球发生一点移动。

将它传递给检查(通过指针的值)不会使其以任何方式初始化

void check(Body* b)
{
    b = new Body();
}

如果你是通过指针来传递的,应该没问题

  void check(Body** b)
  {
     *b = new Body();
  }

还有通话

check(&b);

使用您提供的参考示例以 C++ 方式更好地完成,因为它会更新引用的指针值以指向新分配的 Body

【讨论】:

    【解决方案2】:

    为了等同于checkRef 版本,您的check 函数应为:

    void check(Body** b)
    {
        *b = new Body();
    }
    

    并称为

    check(&b);
    

    如果您没有像在check(b) 中那样传递地址,那么您将传递指针b 的当前,这确实是未初始化的。

    【讨论】:

    • 确实如此。重要的是要记住,“未初始化”更多不仅仅是“不指向任何有意义的东西”或“指向内存中的任意位置”。在未初始化的情况下使用它是无效(严格来说,UB)......无论“使用”是什么意思。
    【解决方案3】:

    Body * &b 中,b 是mainb 的别名/引用 - 因此,当您分配给它时,您会修改main 中的b。在Body* b 中,b 是mainb本地副本,您正在修改此本地副本,而不是main 中的b

    您的运行时错误可能是由于在main 中使用了未初始化的b

    编辑:您得到的实际错误是编译器嵌入到您的代码中的额外检查典型问题机制。它检测到您传递了未按值初始化的内容,这没有意义,因此会生成此错误。

    如果您禁用此行为,应用程序将显示正常运行,直到您尝试取消引用 main 中未初始化的 b

    【讨论】:

    • @demaxSH: 你得到的错误是因为编译器生成代码来检查这些问题 - 你传递的东西没有按值初始化,这在任何方面都没有意义,所以编译器 -生成的检查会产生此错误。如果您在禁用此类额外检查的情况下构建“发布”构建,则不会出现此错误,稍后在尝试使用未初始化的 b 时,您会在应用程序中看到它的症状
    • 是的,我在 gcc 中编译时没有遇到运行时错误。我没有意识到“新”初始化程序会修改指针,现在我知道了
    • @demaxSH:修改指针的不是new,而是对指针的赋值。赋值总是会修改被赋值的对象;这就是它的目的。
    【解决方案4】:

    我不知道您为什么会看到 run-time 错误;最多我希望收到 compile-time 警告/错误。但是您可以通过将 b 初始化为 NULL 来修复它(但这不会修复您的程序;见下文...)

    第一个和第二个函数调用的区别在于第一个会导致内存泄漏。您正在传递指针按值,因此在check() 中,您正在使用该指针的副本。你分配这个副本,但这并不影响main()中指针的值,所以当你离开函数时,没有办法访问new获得的内存。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-30
      • 1970-01-01
      • 2017-10-19
      • 2019-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多