visual studio中c++指针的问题(但在g++中工作)
problem with c++ pointers in visual studio (but works in g++)
当我在Microsoft visual studio中运行以下代码时,它会输出垃圾值(内存地址?),但当它在g++中运行时,它会输出我想要的内容(通过一些更改,如更改srand)。我如何修复它在visual studio工作?我只有几个月的编码经验,这个问题已经困扰我一段时间了。
class Vehicle
{
protected:
int * vin;
double * gasMileage;
public:
Vehicle();
Vehicle(int v, double g);
virtual void display(){cout<<"vin: "<<*vin<<endl<<"gasMileage: " <<*gasMileage<<endl;}
virtual double calcGasUsed(int milesDriven){return *gasMileage * milesDriven;}
int getVin(){return *vin;}
double getGasMileage(){return *gasMileage;}
void changeVin(int newvin) {vin=&newvin;}
void changeGasMileage(double newGasMileage){gasMileage=&newGasMileage;}
void drive();
};
class Suv:public Vehicle
{
protected:
bool *fourWDStatus;
double * fourWDGasMileage;
public:
Suv();
Suv(int v, double g,bool status, double fwdg);
void display();
double calcGasUsed(Suv&, int milesDriven);
bool getFourWDStatus(){return *fourWDStatus;}
double getfourWDGasMileage(){return *fourWDGasMileage;}
void changeFourWDStatus(bool status) {fourWDStatus=&status;}
void changeFourWDGasMileage(double newGasMileage){fourWDGasMileage=&newGasMileage;}
};
Vehicle::Vehicle()
{
this->vin=0000;
this->gasMileage=00;
}
Vehicle::Vehicle(int v, double g)
{
this->vin=&v;
this->gasMileage=&g;
}
Suv::Suv(int v, double g,bool status, double fwdg)
{
this->vin=&v;
this->gasMileage=&g;
this->fourWDStatus=&status;
this->fourWDGasMileage=&fwdg;
}
Suv::Suv()
{
this->vin=0000;
this->gasMileage=00;
this->fourWDStatus=false;
this->fourWDGasMileage=00;
}
void Suv::display()
{
Vehicle::display();
cout<<"fourWDStatus: "<<*fourWDStatus<<endl<<"fourWDGasMileage: "<<*fourWDGasMileage<<endl;
}
void Vehicle::drive()
{
int r=rand()%10000;
cout<<calcGasUsed(r)<<endl;
}
double Suv::calcGasUsed(Suv&, int milesDriven)
{
double x;
if (*fourWDStatus== true)
{
x= ((*fourWDGasMileage) * (milesDriven));
return x;
}
else
{
x=((*gasMileage) * (milesDriven));
return x;
}
}
void main()
{
cout << "test";
srand(NULL);
Suv A(300,12.2,false,16.6);
Suv B(200,15.5,false,20.1);
B.changeFourWDStatus(true);
Vehicle C(111,20.5);
C.drive();
C.display();
B.display();
Vehicle arrOfCars[]={A,B,C};
A.drive();
B.drive();
C.drive();
system("pause");
}
您在使用指针时没有将其初始化为任何东西。我很快就发现,成员变量都不应该是指针,构造函数参数都不应该是引用。在其他地方,将int赋值给int*。编译器给你警告了吗?
两个更奇怪的事情:为什么用四位数字的0000
作为整数字面值,为什么用system("pause")
?
不要将类的数据成员存储为指针。没有必要给出你的用法。乍一看,我发现这里有一个问题:
void changeGasMileage(double newGasMileage){gasMileage=&newGasMileage;}
这样做的是将gasMileage设置为指向堆栈上分配的值。当changeGasMileage
返回时,您不再知道该内存位置上的内容。您可以将gasMileage
设置为一个值而不是一个指针。否则,您需要执行:
void changeGasMileage(double newGasMileage){gasMileage= new double(newGasMileage);}
成员Vehicle::vin
、Vehicle::gasMileage
和Suv::fourWDStatus
、Suv::fourWDGasMileage
是未正确初始化的指针。
从你发布的代码看来,你会更好地将它们从指针改为常规变量(并适当地调整方法)。
编辑:如果使用指针是赋值操作的一部分,则必须正确初始化它们。这意味着,在您的情况下,在构造函数中分配内存。可以是这样的:
Vehicle::Vehicle()
{
this->vin = new int(0);
this->gasMileage = new double(0.0);
}
Vehicle::Vehicle(int v, double g)
{
this->vin = new int(v);
this->gasMileage = new double(g);
}
Suv::Suv(int v, double g,bool status, double fwdg) : Vehicle(v, g)
{
this->fourWDStatus = new bool(status);
this->fourWDGasMileage = new double(fwdg);
}
Suv::Suv() : Vehicle(0, 0.0)
{
this->fourWDStatus = new bool(false);
this->fourWDGasMileage = new double(0.0);
}
其他人已经讨论了不适合此场景的指针的使用。我同意。
同样,当构造函数接收到按值复制时,要获取其地址的值驻留在(调用)堆栈上。当该构造函数退出时,局部变量被解构(对于内置类型,int, char, float等通常是无操作的),并且通过指针访问它们是"未定义行为"。
为什么会这样: 未定义的行为意味着允许任何事情发生。最好是编译器诊断,或者是崩溃,或者更糟糕的是,可以看到损坏的数据,但最坏的情况是,巧合使它工作到稍后一段时间-参见巧合编程。
一旦构造函数退出,这个区域将被打开,以便在调用其他函数时重用——它们将需要一个地方来存储它们的局部变量、参数和调用其他函数的参数/返回地址。
巧合的是,gcc(那个版本,那些编译器标志)并没有覆盖堆栈上用于打印值的位置,因此您读取的值就是您期望的值。
- 代码在main()中运行,但在函数中出现错误
- 链接阶段在Ubuntu上失败,但在MacOS上失败
- 对C宏的未定义引用,但在定义它时会出现重新定义错误
- c++17文件系统::recursive_directory迭代器()在mac上没有给出这样的目录,但在windows上
- 断言中的Fold表达式在某些计算机上编译,但在其他计算机上不编译
- 换位表导致测试失败(但在游戏中运行良好)
- 库标题在标题中不可见,但在 cmake build 下.cpp文件中完全可见.为什么?
- 树莓上的 Libtorch 无法加载 pt 文件,但在 ubuntu 上工作
- 在成员dynamic_bitset上使用 boost::from_block_range 时出错,但在本地dynamic
- 编译在我的 Mac 上工作,但在集群 (Linux) 上不起作用
- 我编写了代码将十进制分数转换为其二进制等效数.它编译得很好,但在执行时挂起
- 我的代码运行良好,但在游戏循环中中断
- C++ assigment std::list:<typename>:itrator 在 main 中工作,但在方法中它不起作用
- C++代码在台式机上工作正常,但在笔记本电脑上则不行
- 实现 DFS 在较短的输入下工作正常,但在较大的输入下会抛出分段错误
- 点云库在VS 2019中不起作用,但在VS 2017中确实有效
- C++ Python 模块在 Blender 中崩溃,但在 Python 控制台中不会崩溃
- 分段 Linux Ubuntu 中的 g++ 错误,但在 Windows 中的 g++/MingW 中,在 C++ 中打
- 为什么数组大小信息可用于"sizeof"运算符和 delete[] 运算符,但在将数组作为参数传递到
- 如何处理没有默认构造函数但在另一个构造函数中构造的对象?