Delphi中的未初始化变量是否保证具有任何特定值
由于C ++ Builder一般遵循Delphi的设计,C ++ Builder中的未初始化变量保证具有任何特定值
我继承了一些C ++ Builder代码,这些代码很大程度上取决于成员变量的零初始化,并试图弄清楚语言是否能保证这一点。
当Windows首次提供给程序的堆栈或堆时,Windows是否保证内存为零初始化? (编辑:我意识到程序会在执行时覆盖内存,所以它不能继续依赖于此;我只是想弄清楚我观察到的行为。)
答案 0 :(得分:7)
因为caskey的回答只涉及c ++我对delphi的回答:
在delphi中,请this answer
引用Giacomo Degli EspostiMS-帮助://borland.bds4/bds4ref/html/Variables.htm
的所有学分编辑:“当Windows首次提供给程序的堆栈或堆时,Windows是否保证内存零初始化?”
Windows保证在首次将内存初始化为新进程时对内存进行零初始化(否则,无论权限如何,程序都能够读取其他进程丢弃的内存时会遇到很大的安全问题)。但是使用c ++这个保证对你没有多大帮助,因为在你的代码有机会使用它之前,c-runtime可以自行覆盖内存。
Edit2 :对于c ++构建器变量显然是为“ VCL样式类”初始化的(无论这意味着什么,都是从TObject继承的?),请参阅{{3 }}
我引用:
“因为数据成员可能在虚拟功能中使用,所以重要的是 了解它们何时以及如何初始化。在Object Pascal中,所有未初始化的数据 是零初始化。例如,这适用于构造函数所在的基类 不用继承调用。 在标准C ++中,无法保证其价值 未初始化的数据成员。以下类型的类数据成员必须是 在类的构造函数的初始化列表中初始化: •参考文献 •没有默认构造函数的数据成员
尽管如此,这些数据成员的价值,还是那些在正文中初始化的成员 构造函数,在调用基类构造函数时是未定义的。 在C ++ Builder中, VCL样式类的内存为零初始化。
从技术上讲,它是VCL或CLX类的内存为零,即位是 零,这些值实际上是未定义的。例如,引用为零。
一个虚函数,它依赖于在中初始化的成员变量的值 构造函数的主体或初始化列表中的行为可能就像变量一样 初始化为零。这是因为基类构造函数在之前被调用 处理初始化列表或输入构造函数体。
#include <sysutils.hpp>
class Base : public TObject {
public:
__fastcall Base() { init(); }
virtual void __fastcall init() { }
};
class Derived : public Base {
public:
Derived(int nz) : not_zero(nz) { }
virtual void __fastcall init()
{
if (not_zero == 0)
throw Exception("not_zero is zero!");
}
private:
int not_zero;
};
int main(void)
{
Derived *d42 = new Derived(42);
return 0;
}
此示例在Base的构造函数中引发异常。因为Base是 在Derived之前构造的not_zero尚未使用值42初始化 传递给构造函数。请注意,您无法初始化您的数据成员 调用基类构造函数之前的VCL样式类。“
答案 1 :(得分:2)
简短回答:在C ++中你必须初始化所有内容
如果C ++ Builder与C ++类似,那么除非你明确地初始化它,否则不能保证内存的内容。
虽然Windows可能会在页面可用于程序的堆栈或堆之前留空,但除非您从操作系统请求自己的内存,否则您可能正在使用构造函数或库来进行内存分配。您经常会获得自己已经使用过的页面或内存区域。在这种情况下,它几乎可以保证是脏的。对于几乎从不是新页面的堆栈页面来说也是如此。
memset()将是您在C中擦除内存的方式,但在C ++中,您需要为每个字段提供默认值,或者在构造函数中显式初始化它们。
答案 2 :(得分:1)
在C ++中,保证在以下情况下初始化内存:
在第一种情况下,POD数据类型(如整数,指针等)将初始化为零。
这些是C ++标准提供的唯一保证。 Windows在此区域根本不提供任何保证。
答案 3 :(得分:1)
在Delphi中,TObject构造函数初始化堆分配的(总是在堆上,因为TObject不能在Delphi中进行堆栈实例化)对象的内存,从而清除所有成员变量。
答案 4 :(得分:0)
在Delphi上,据我所知: * vcl类自动初始化其字段。 * Globals太
本地变量未已初始化。他们的初始内容完全未定义。因此,如果变量是本地的,TObject类型的Assigned(变量)将一直返回 false 。