指针初始化时也会产生崩溃

Pointer generate a crash also if it is initialized

本文关键字:崩溃 初始化 指针      更新时间:2023-10-16

我正在测试这段代码,结果是程序在到达第一个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相同。