我想知道以下C++代码出了什么问题。它在运行时崩溃。
#include <iostream.h>
#include <conio.h>
using namespace std;
class node
{
public:
int info;
node *addr;
node(){
info = 0;
addr = NULL;
}
~node(){}
};
void func(node *);
int main(void){
node *head;
node b;
b.info = 10;
*head = b;
func(head);
getch();
}
void func(node *obj){
cout<<"i: "<<(*obj).info;
}
*head = b;
不正确,因为头部没有指向任何东西
head = &b ;
应该解决问题
似乎问题出在
*head = b;
将其替换为
head = &b ;
有一件事是你在这里声明了一个指针:
node *head;
然后在这里使用它:
*head = b;
无需为head
分配内存。
行*head = b;
应该是head = &b;
的,假设你想将b
的地址分配给指针head
。
错误版本可以编译,但它会将对象的副本b
分配给未初始化指针中包含的地址。
其他人已经回答了你的写入任意内存问题,但我想专注于其他一些事情,例如:
#include <iostream.h>
#include <conio.h>
这样做的问题在于您使用的是严重过时的编译器。C++标头上不再有.h
,并且conio.h
严重不标准且老化。
我建议首先更新到更新的环境。
此外,OO的基石之一是对象对自己的行为负责。代码到达对象内部以直接访问成员几乎从来都不是一个好主意。
你应该提供适当的getter和setter,并且通常确保类中唯一的公共内容是函数而不是数据。
换句话说,像这样:
class node {
public:
node () {
info = 0;
addr = NULL;
}
~node() {
}
int getInfo() {
return info;
}
void setInfo (int newInfo) {
// Check newInfo for validity first.
info = newInfo;
}
node *getAddr() {
return addr;
}
void setAddr (node *newAddr) {
// Check newAddr for validity first.
addr = newAddr;
}
private:
int info;
node *addr;
};
我看到两个问题:
-
引用未初始化的指针
*head
-
将堆栈变量存储在指针中。
我(像其他人一样)认为当你说*head = b
时,你真的是head = &b
的意思。 在第一种情况下,引用节点指针并在其上分配节点值。 这是一个错误,因为head
变量尚未初始化,因此您将完整节点值复制到无效内存地址之上。
如果替换为head = &b
,则稍微好一些,因为现在您将head
指针设置为b
的地址。 但是现在你遇到了另一个错误,因为b
是一个堆栈变量,所以那里的指针仅在函数的生命周期内有效。 一旦函数完成,堆栈空间将被重用,head
指针会破坏那里的任何内容。
典型的解决方案是保留head
作为指向节点的指针,但也b
更改为指向节点的指针,并使用堆内存分配对其进行初始化,例如b = (node *)malloc(sizeof(node);
或b = new node;
。 然后你可以在*b
中存储任何内容,最后存储指向生存期较长的变量的指针,如heap=b;
。