我正在测试这段代码,结果是程序在第一个<< op
到达cout
时崩溃(因为它打印出op =
然后停止)
char *lo = 0, *op = 0, *ro = 0;
cout << "op = " << op << endl;
cout << "*op = " << *op << endl;
现在我的问题是:为什么会这样?
我知道,指针给我带来了很多问题..
答案 0 :(得分:6)
因为在这里:
cout << "*op = " << *op << endl;
// ^^^
// op is a NULL pointer!
您正在取消引用一个不指向任何对象的指针,这是未定义的行为。
因此,尽管指针已初始化,但它未使用现有对象的地址进行初始化,因此您无法有意义地取消引用它。 C ++ 11标准的第5.3.1 / 1段规定:
一元
*
运算符执行间接:应用它的表达式应该是指向的表达式 对象类型,或指向函数类型的指针,结果是引用对象或函数的左值 表达点。
当表达式没有指向任何对象时,标准没有指定结果应该是什么:因此,它是未定义的行为。
答案 1 :(得分:4)
您的问题可以归纳为:
我被教导说取消引用未初始化的指针是不好的,并得出结论,这意味着所有初始化指针必须是好的。我是对的吗?
答案是响亮的否。
未初始化的指针不是问题。
问题在于指针没有指向内存中的某些正常存储。对于未初始化的指针通常就是这种情况,但当故意为指针分配一些无用的值时,也就像这里一样。
为了指向一个字符串,0
是一个无用的值,因为它表示“这个指针不指向任何地方”。然后尝试取消引用它是不行的。
您对此代码的不同行为并不完全清楚。
答案 2 :(得分:1)
按照你的标题“指针在初始化时也会生成崩溃”。
您创建的指针未初始化为任何内存位置。初始化指向0
的指针时,表示您是initialising it to NULL。
pointer应该保存一个内存地址(在你计划使用*
之前)或NULL(通过修改随机内存位置来防止它出现问题,直到你分配一些内存位置为止在解除引用之前,它还表示指针当前处于非活动状态。
char *lo = 0, *op = 0, *ro = 0;
您的指针当前为NULL,未指向任何memory location。
char a = 'A';
char * lo = &a; / char* lo = new char[10]; etc
取消引用未初始化或NULL指针为undefined behaviour。
答案 3 :(得分:1)
您的程序已在
上崩溃cout << "op = " << op << endl;
行,因为<<
的{{1}}运算符重载,它将它们解释为指向0终止字符数组的初始元素的指针,并在下一个0字节之前打印字符out,因此需要取消引用指针。但是你初始化char*
是一个空指针,因此取消引用它会调用未定义的行为,通常会导致崩溃(分段错误)。
将op
转换为其他指针类型,例如一个op
void*
将使该行工作并打印一个实现定义的空指针表示。
然后,您仍然会在下一行显示未定义的行为(很可能是崩溃),您明确取消引用cout << "op = " << static_cast<void*>(op) << endl;
。
答案 4 :(得分:0)
这是因为你初始化指针指向地址零,这与NULL
相同。