0

我正在测试这段代码,结果是程序<< op在第一次到达时崩溃cout(因为它打印出来op =然后停止)。

char *lo = 0, *op = 0, *ro = 0;
cout << "op = " << op << endl;
cout << "*op = " << *op << endl;

现在我的问题是:为什么会这样?

我知道,指针给我带来了很多问题..

4

5 回答 5

6

因为这里:

cout << "*op = " << *op << endl;
//                  ^^^
//                  op is a NULL pointer!

您正在取消引用一个不指向任何对象的指针,这是未定义的行为。

因此,尽管指针已初始化,但它并未使用现有对象的地址进行初始化,因此您无法有意义地取消引用它。C++11 标准的第 5.3.1/1 段规定:

一元运算*符执行间接:应用它的表达式应该是指向对象类型的指针,或指向函数类型的指针,结果是一个左值,指向表达式指向的对象或函数

当表达式不指向任何对象时,标准没有指定结果应该是什么:因此,它是未定义的行为。

于 2013-05-23T12:31:30.307 回答
4

简短的回答

您的问题可以总结如下:

我被告知取消引用未初始化的指针是不好的,并且得出的结论是这意味着所有已初始化的指针都必须是好的。我对吗?

答案是响亮的


长答案

未初始化的指针不是问题。

问题在于指针不指向内存中一些体面的存储。这通常是未初始化的指针的情况,但是当您故意为指针分配一些无用的值时也是这种情况,就像这里一样。

对于指向一个字符串的目的,0是一个无用的值,因为它表示“这个指针没有指向任何地方”。然后尝试取消引用它是不行的。

尚不完全清楚您期望从这段代码中获得什么不同的行为。

于 2013-05-23T12:34:16.063 回答
1

按照您的标题“指针在初始化时也会产生崩溃”。

您创建的指针未初始化到任何内存位置。当您初始化指向0它的指针时,意味着您将其初始化为 NULL

指针应该保存一个内存地址(在您计划使用*它之前)或 NULL(通过修改随机内存位置来防止它引起问题,直到您为其分配一些内存位置,然后再取消引用。它还表明指针当前处于非活动状态)。

char *lo = 0, *op = 0, *ro = 0;

您的指针当前为 NULL,未指向任何内存位置

char a = 'A';
char * lo = &a; / char* lo = new char[10]; etc

取消引用未初始化或 NULL 指针是未定义的行为

于 2013-05-23T12:42:20.677 回答
1

您的程序已经在

cout << "op = " << op << endl;

行,因为有一个<<运算符的重载,char*它将它们解释为指向以 0 结尾的字符数组的初始元素的指针,并在下一个 0 字节输出之前打印字符,因此需要取消引用指针。但是您初始化op为空指针,因此取消引用它会调用未定义的行为,通常会导致崩溃(分段错误)。

转换op为不同的指针类型,例如void*

cout << "op = " << static_cast<void*>(op) << endl;

将使该行工作并打印空指针的实现定义的表示。

然后,在您明确取消引用的下一行,您仍然会有未定义的行为(并且很可能是崩溃)op

于 2013-05-23T12:47:51.743 回答
0

这是因为您将指针初始化为指向地址零,这与 a 相同NULL

于 2013-05-23T12:31:51.980 回答