我正在测试这段代码,结果是程序<< op
在第一次到达时崩溃cout
(因为它打印出来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 段规定:
一元运算
*
符执行间接:应用它的表达式应该是指向对象类型的指针,或指向函数类型的指针,结果是一个左值,指向表达式指向的对象或函数。
当表达式不指向任何对象时,标准没有指定结果应该是什么:因此,它是未定义的行为。
您的问题可以总结如下:
我被告知取消引用未初始化的指针是不好的,并且得出的结论是这意味着所有已初始化的指针都必须是好的。我对吗?
答案是响亮的不。
未初始化的指针不是问题。
问题在于指针不指向内存中一些体面的存储。这通常是未初始化的指针的情况,但是当您故意为指针分配一些无用的值时也是这种情况,就像这里一样。
对于指向一个字符串的目的,0
是一个无用的值,因为它表示“这个指针没有指向任何地方”。然后尝试取消引用它是不行的。
尚不完全清楚您期望从这段代码中获得什么不同的行为。
按照您的标题“指针在初始化时也会产生崩溃”。
您创建的指针未初始化到任何内存位置。当您初始化指向0
它的指针时,意味着您将其初始化为 NULL。
指针应该保存一个内存地址(在您计划使用*
它之前)或 NULL(通过修改随机内存位置来防止它引起问题,直到您为其分配一些内存位置,然后再取消引用。它还表明指针当前处于非活动状态)。
char *lo = 0, *op = 0, *ro = 0;
您的指针当前为 NULL,未指向任何内存位置。
char a = 'A';
char * lo = &a; / char* lo = new char[10]; etc
取消引用未初始化或 NULL 指针是未定义的行为。
您的程序已经在
cout << "op = " << op << endl;
行,因为有一个<<
运算符的重载,char*
它将它们解释为指向以 0 结尾的字符数组的初始元素的指针,并在下一个 0 字节输出之前打印字符,因此需要取消引用指针。但是您初始化op
为空指针,因此取消引用它会调用未定义的行为,通常会导致崩溃(分段错误)。
转换op
为不同的指针类型,例如void*
cout << "op = " << static_cast<void*>(op) << endl;
将使该行工作并打印空指针的实现定义的表示。
然后,在您明确取消引用的下一行,您仍然会有未定义的行为(并且很可能是崩溃)op
。
这是因为您将指针初始化为指向地址零,这与 a 相同NULL
。