指针初始化时也会产生崩溃
Pointer generate a crash also if it is initialized
我正在测试这段代码,结果是程序在到达第一个cout
中的<< op
时崩溃(因为它打印出op =
然后停止)。
char *lo = 0, *op = 0, *ro = 0;
cout << "op = " << op << endl;
cout << "*op = " << *op << endl;
现在我的问题是:为什么会这样?
我知道,指针给我带来了很多问题。
因为这里:
cout << "*op = " << *op << endl;
// ^^^
// op is a NULL pointer!
你正在解引用一个不指向任何对象的指针,这是未定义的行为。
因此,虽然指针被初始化,但它不是用现有对象的地址初始化的,因此不能有意义地对其解引用。c++ 11标准第5.3.1/1段规定:
一元
*
操作符是间接执行的:它所作用的表达式必须是指向an的指针对象类型,或指向函数类型的指针,结果是指向对象或函数的左值.
标准没有指定表达式不指向任何对象时的结果应该是什么:因此,它是未定义的行为。
简短回答
你的问题可以总结如下:
我被告知对未初始化的指针解引用是不好的,并得出结论,这意味着所有初始化的指针都必须是好的。我说的对吗?
答案是响亮的不。
长回答
未初始化的指针不是问题。
问题是指针不指向内存中一些体面的存储。这通常是未初始化指针的情况,但也是的情况,当故意为指针分配一些无用的值时,就像这里一样。
对于指向字符串的目的,0
是一个无用的值,因为它表示"该指针不指向任何地方"。那么尝试解引用它是不行的。
你的程序已经崩溃了
cout << "op = " << op << endl;
行,因为char*
的<<
操作符重载,将它们解释为指向以0结尾的字符数组的初始元素的指针,并打印出下一个0字节之前的字符,因此需要对指针解引用。但是您将op
初始化为空指针,因此解引用它会调用未定义的行为,通常会导致崩溃(分段错误)。
将op
转换为不同的指针类型,例如void*
cout << "op = " << static_cast<void*>(op) << endl;
将使这行正常工作,并打印实现定义的空指针表示形式。
那么在下一行中您仍然会有未定义的行为(并且很可能崩溃),在这里您显式地解引用op
。
根据你的标题"指针生成崩溃也如果它被初始化"。
您创建的指针未初始化为任何内存位置。当你初始化一个指向0
的指针时,这意味着你将它初始化为NULL。
指针应该保存一个内存地址(在你计划对它使用*
之前)或NULL(为了防止它通过修改随机内存位置而引起问题),直到你给它分配一些内存位置,在解引用之前。它还表明指针当前处于非活动状态)。
char *lo = 0, *op = 0, *ro = 0;
指针当前为NULL,不指向任何内存位置。
char a = 'A';
char * lo = &a; / char* lo = new char[10]; etc
对未初始化或NULL指针的解引用是未定义的行为。
这是因为您初始化指针指向地址0,这与NULL
相同。
- 内联映射初始化的动态atexit析构函数崩溃
- 字节数组初始化会导致 DirectX 崩溃
- Canon SDK初始化崩溃
- 正则表达式在 Windows 上初始化时崩溃
- 使用C 扩展Python/numpy,模块在初始化时崩溃
- 在构造函数因未初始化成员而崩溃之前调用的C++函数
- C++初始化复制构造函数中的列表赋值,并在复制构造函数中崩溃
- 要释放动态数组初始化时程序崩溃
- C++初始化指针会使应用程序随机崩溃
- C 指针崩溃(非初始化)
- 一次崩溃了SDL_MIXER;现在,所有使用SDL_MIXER的程序在初始化时崩溃
- GDI 初始化崩溃了应用程序
- Android OpenSL ES在初始化时崩溃
- Visual Studio 2013 因非静态数据成员初始化而崩溃
- C++ 动态数组初始化崩溃
- 内存导致程序崩溃并带有初始化的目的地
- 重新初始化字符串对象时发生崩溃
- 协议缓冲区初始化期间崩溃
- 我的矩阵类在初始化时崩溃
- 指针初始化时也会产生崩溃