【问题标题】:Can I get a pointer to a pointer pointing to nullptr, is it valid我可以获得指向指向 nullptr 的指针的指针,它是否有效
【发布时间】:2017-10-20 15:21:16
【问题描述】:

我对下面的代码有些疑惑:

void b(int** a){
        int *c = new int;
        *a = c;
        **a = 120;
}

int main(){
        int *a = nullptr;
        b(&a);
        if(a)
                delete a;
        return 0;
}

我担心这可能会导致 UB,因为它是一个 nullptr,并且我正在更改指针地址,因为我正在获取对它的引用,但后来我开始认为这不应该是我将遇到的问题。 一些地址-> nullptr。而且这个地址是有效的,所以我可以更改它。

我多次运行此测试并启用了 -fsanitize=address,它运行良好。 但是,这是正确的吗?

【问题讨论】:

  • 你有内存泄漏,但这是我能看到的唯一问题。
  • 记住:双星程序员比单星程序员差,单星程序员比无星程序员差。
  • @cheers 除了three star programmers,这是最好的。
  • @BaummitAugen 这比我住过的一些酒店的星级还要多。
  • 在一个有点相关的注释上,你可以delete一个空指针(它是一个noop),不需要检查。

标签: c++ dereference


【解决方案1】:

我担心这可能会导致 UB,因为它是一个 nullptr

b() 的参数a 不是nullptr,它会在取消引用之前分配指向的指针,所以这不是问题。

【讨论】:

  • 澄清一下:b()不影响nullptr,只影响a,已经初始化为nullptr,但可以随意更改
【解决方案2】:

我不认为你有内存泄漏,但你必须非常小心这样的事情:

#include <iostream>

void b(int** a)
{
  int *c = new int;
  *a = c;
  **a = 120;

  // if C is deleted then the *a needs to be set to nullptr
  //delete c;
  //*a = nullptr;

  // Not needed as this will just be defeferenced off the stack
  // *a and c are two different pointers in memory so this is fine
  c = nullptr;
}

int main(){
  int *a = nullptr;
  std::cout << "Before B, a=" << a << std::endl;
  b(&a);
  std::cout << "After B, a=" << a << std::endl;
  std::cout << "After B, *a=" << *a << std::endl;
  if(a)
  {
    delete a;
  }

  // a still has a pointer with an address and can't be trusted
  std::cout << "End A, a=" << a << std::endl;
  // On repl.it, it prints 0
  std::cout << "End *a, a=" << *a << std::endl;

  return 0;
}

【讨论】:

  • c = nullptr; 是不必要的,因为c 之后立即超出范围。此外,您最后的cout 将招致未定义行为的愤怒。
  • 是的,cmets 说了这么多。我还可以补充一点,您可以在最后在 b 中执行 'a = nullptr',这并不重要。
  • 当然,我同意,这就像一个代表问题的小代码,指针被传递,这就是它有这么多缺陷的原因,就像在几分钟内完成的代码一样 :)
猜你喜欢
  • 1970-01-01
  • 2019-06-12
  • 1970-01-01
  • 1970-01-01
  • 2011-08-04
  • 1970-01-01
  • 1970-01-01
  • 2011-04-24
  • 1970-01-01
相关资源
最近更新 更多