为什么默认情况下没有使用NULL初始化指针?

Jon*_*han 117 c++ memory pointers initialization

有人可以解释为什么指针没有初始化NULL
例:

  void test(){
     char *buf;
     if (!buf)
        // whatever
  }
Run Code Online (Sandbox Code Playgroud)

程序不会进入if,因为buf它不是null.

我想知道为什么,在什么情况下我们需要一个带垃圾的变量,特别是指针解决内存上的垃圾问题?

Mar*_*ork 159

我们都意识到应该初始化指针(和其他POD类型).
那么问题就变成了"谁应该初始化它们".

那么基本上有两种方法:

  • 编译器初始化它们.
  • 开发人员初始化它们.

我们假设编译器初始化了未由开发人员显式初始化的任何变量.然后我们遇到这样的情况:初始化变量是非常重要的,开发人员在声明点没有这样做的原因是他/她需要执行一些操作然后分配.

所以现在我们遇到这样的情况:编译器已经向代码添加了一条额外的指令,该指令将变量初始化为NULL,然后添加开发人员代码以进行正确的初始化.或者在其他条件下,变量可能永远不会被使用.许多C++开发人员会在这两个条件下以这个额外指令为代价尖叫犯规.

这不仅仅是时间问题.还有空间.在很多环境中,两种资源都非常宝贵,开发人员也不想放弃.

但是:您可以模拟强制初始化的效果.大多数编译器会警告您未初始化的变量.所以我总是将警告级别变为可能的最高级别.然后告诉编译器将所有警告视为错误.在这些条件下,大多数编译器将为未初始化但使用的变量生成错误,从而阻止生成代码.

  • 鲍勃·塔博尔说:"太多人没有充分考虑初始化!"它"友好"自动初始化所​​有变量,但需要时间,慢速程序"不友好".显示随机垃圾malloc的电子表格或编辑器是不可接受的.C,对于训练有素的用户来说是一个尖锐的工具(如果误用则是危险的)不应该花时间初始化自动变量.初始变量的训练轮宏可能是,但许多人认为站起来,注意和流血更好.在紧要关头,你按照练习的方式工作.所以练习就像你一样. (5认同)
  • @Loki,我很难跟上你的观点.我只是想把你的答案称为有帮助,我希望你收集到了.如果不是,我很抱歉. (4认同)
  • 您会惊讶于仅仅通过修复所有初始化就可以避免多少错误。如果不是编译器警告,这将是乏味的工作。 (2认同)
  • 如果指针首先设置为NULL然后设置为任何值,编译器应该能够检测到这一点并优化第一个NULL初始化,对吧? (2认同)

Joh*_*ohn 40

引用TC++ PL中的Bjarne Stroustrup(特别版第22页):

功能的实现不应对不需要它的程序施加显着的开销.

  • @ Jonathan没有什么可以阻止你将指针初始化为null - 或者是C++标准的0. (8认同)
  • 是的,但斯特劳斯可以通过零初始化的指针已经成为默认的语法,有利于程序的正确性,而不是性能,使程序员必须明确地请求指针未被初始化.毕竟,大多数人更愿意正确的,但慢了快但很错误的,理由是它通常更容易优化比整个程序修复漏洞少量的代码.特别是当它的大部分可以由一个体面的编译器完成. (7认同)
  • 我喜欢'D`的作用.如果你不想初始化,请使用这个语法`float f = void;`或`int*ptr = void;`.现在它默认初始化,但如果你真的需要,你可以阻止编译器这样做. (4认同)
  • 它不会破坏兼容性。该想法已与“int* x = __uninitialized”结合考虑 - 默认安全,意图速度。 (2认同)

小智 23

因为初始化需要时间.在C++中,你应该对任何变量做的第一件事是明确地初始化它:

int * p = & some_int;
Run Code Online (Sandbox Code Playgroud)

要么:

int * p = 0;
Run Code Online (Sandbox Code Playgroud)

要么:

class A {
   public:
     A() : p( 0 ) {}  // initialise via constructor
   private:
     int * p;
};
Run Code Online (Sandbox Code Playgroud)

  • 如果你没有明确地初始化它就永远不会使用指针,那么在你给它一个值之前它包含什么并不重要,并且根据C和C++原则只支付你使用的东西,它没有完成自动.如果有可接受的默认值(通常是空指针),则应初始化它.您可以初始化它或保持未初始化,您的选择. (4认同)
  • @Jonathan:但是null也是垃圾.使用空指针无法做任何有用的事情.取消引用一个也是一个错误.使用适当的值创建指针,而不是空值. (3认同)
  • 初始化apointer到Nnull可以是do.And还有你可以在空指针执行若干操作一个明智的做法 - 你可以对其进行测试,并且可以调用删除它们. (2认同)

Kea*_*eks 20

因为C++的一个支柱是:


你不支付你不需要的东西


出于这个原因,例如operator[],vector类的类不会检查索引是否超出范围.


Ara*_*raK 12

由于历史原因,主要是因为这是在C中完成的.为什么它在C中完成,是另一个问题,但我认为零开销原则在某种程度上涉及到这个设计决策.


Jos*_*hua 8

此外,我们确实有一个警告,当你打击它时:"可能在分配值之前使用"或类似的verbage,具体取决于你的编译器.

你确实编译了警告,对吧?


DrP*_*zza 6

很少有几种情况可以使变量未初始化,而默认初始化的成本很低,为什么呢?

C++不是C89.天哪,连C都不是C89.您可以混合声明和代码,因此您应该推迟声明,直到您有一个合适的值来初始化.

  • 然后只需将每个值写入两次 - 一次由编译器的安装程序,再由用户程序编写.通常不是一个大问题,但它会增加(例如,如果你创建一个包含100万个项目的数组).如果你想要自动初始化,你总是可以创建自己的类型来做到这一点; 但是这样你就不会被迫接受不必要的开销,如果你不想这样做的话. (2认同)