[英]C++: dll not working on Visual Studio 2017 but works with 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
以及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等通常為no-op),並且通過指針訪問它們是“未定義的行為”。
為什么這樣發生: 未定義的行為意味着任何事情都可以發生。 最好是編譯器診斷程序,或者是崩潰程序,或者更糟糕的是,它仍然可以看到為損壞的數據,但是最壞的情況是,巧合使它可以工作到以后的某個時間-另請參見“ 巧合編程” 。
一旦構造函數退出,該區域將在調用其他函數時開放供重用-他們將需要一個地方來存儲其局部變量,參數和參數/返回地址,以調用其他函數。
碰巧的是,gcc(該版本,那些編譯器標志)不會覆蓋堆棧上用於打印值的位置,因此,您讀取的值就是您期望的值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.