C++动态数组访问冲突
**** 对于原帖中关于 numCars 的混淆,我们深表歉意。我修改了代码,使其与原来的一致 *****
以下学术程序是原始问题的简化版本,但它重点关注我尚未解决的问题。该问题有 2 个类和一个 main 方法,这 2 个类由 Dealer 类和 Car 类组成。 Dealer 类有一个私有 Car* 指针,该指针在 Dealer 的构造函数中初始化为动态数组。当调用 Dealer 的 addCar 方法时,main 方法中出现该错误。 在 main 方法中,我有意将 Dealer 变量传递给 addCar(Dealer&d) 方法以模仿原始应用程序的结构。然后,addCar 方法调用 Dealer 的 addCar(const Car& car) 方法,当我执行 cars[numCars++]=car; 时,会发生访问冲突;你能解释一下为什么 cars[numCars++]=car 会导致访问冲突
/**********************************Dealer.h**************************/
#include <cstdlib>
#include "Car.h"
using namespace std;
class Dealer
{
public:
Dealer(int maxCars = DEFAULT_MAX_CARS)
:numCars(0) {cars = new Car[maxCars];}
~Dealer(){delete [] cars;}
int getTotalCars() const { return numCars;}
void addCar(const Car& car)
{
cars[numCars++] = car; // Access Violation
}
Car* begin(){return cars;};
Car* end(){ return cars + numCars;}
setNumCars(int count){numCars = count;}
private:
static const int DEFAULT_MAX_CARS = 10;
Car* cars;
int numCars;
};
/**********************************Car.h**********************/
#include <cstdlib>
#include <string>
using namespace std;
class Car{
public:
Car()
: year(0), make(""), model("")
{}
Car(int year, string make, string model)
: year(year), make(make), model(model)
{}
string getMake() const {return make;}
void setMake(string make){this->make=make;}
string getModel() const {return model;}
void setModel(string model){this->model=model;}
int getYear() const {return year;}
void setYear(int year){this->year=year;}
private:
int year;
string make;
string model;
};
ostream& operator<< (ostream& out, const Car& car)
{
out << car.getYear() << " " << car.getMake() << " " << car.getModel();
return out;
}
/**********************************Main.cpp**********************/
#include <cstdlib>
#include <iostream>
#include "Dealer.h"
using namespace std;
void addCar(Dealer& d);
int main(int argc, char *argv[])
{
Dealer d;
addCar(d);
system("PAUSE");
return EXIT_SUCCESS;
}
void addCar(Dealer& d)
{
d = Dealer();
d.addCar(Car(2007, "Honda", "Civic"));
cout << d.getTotalCars() << " total cars" << endl;
}
**** Sorry for the confusion regarding numCars in the original post. I modified the code to be consistent with the original ******
The following academic program is a simplified version of the original problem but it focuses on the issue that I have yet to resolve. There are 2 classes and a main method to this problem and the 2 classes consist of a Dealer class and a Car class. The Dealer class has a private Car* pointer that is initialized to a dynamic array in the Dealer's constructor. The error occurs in the main method when the Dealer's addCar method is invoked.
In the main method I intentionally pass the Dealer variable to the addCar(Dealer& d) method to mimic the structure of the original application. The addCar method then invokes the Dealer's addCar(const Car& car) method where the access violation occurs when I execute cars[numCars++]=car; Can you explain why cars[numCars++]=car results in an access violation
/**********************************Dealer.h**************************/
#include <cstdlib>
#include "Car.h"
using namespace std;
class Dealer
{
public:
Dealer(int maxCars = DEFAULT_MAX_CARS)
:numCars(0)
{cars = new Car[maxCars];}
~Dealer(){delete [] cars;}
int getTotalCars() const { return numCars;}
void addCar(const Car& car)
{
cars[numCars++] = car; // Access Violation
}
Car* begin(){return cars;};
Car* end(){ return cars + numCars;}
setNumCars(int count){numCars = count;}
private:
static const int DEFAULT_MAX_CARS = 10;
Car* cars;
int numCars;
};
/**********************************Car.h**********************/
#include <cstdlib>
#include <string>
using namespace std;
class Car{
public:
Car()
: year(0), make(""), model("")
{}
Car(int year, string make, string model)
: year(year), make(make), model(model)
{}
string getMake() const {return make;}
void setMake(string make){this->make=make;}
string getModel() const {return model;}
void setModel(string model){this->model=model;}
int getYear() const {return year;}
void setYear(int year){this->year=year;}
private:
int year;
string make;
string model;
};
ostream& operator<< (ostream& out, const Car& car)
{
out << car.getYear() << " " << car.getMake() << " " << car.getModel();
return out;
}
/**********************************Main.cpp**********************/
#include <cstdlib>
#include <iostream>
#include "Dealer.h"
using namespace std;
void addCar(Dealer& d);
int main(int argc, char *argv[])
{
Dealer d;
addCar(d);
system("PAUSE");
return EXIT_SUCCESS;
}
void addCar(Dealer& d)
{
d = Dealer();
d.addCar(Car(2007, "Honda", "Civic"));
cout << d.getTotalCars() << " total cars" << endl;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您永远不会初始化 numCars - 它包含堆中的一些值,该值几乎肯定非零。这会导致您读取超出 cars 数组末尾并进入无法访问的内存。您应该在构造函数中将 numCars 设置为 0。
最重要的是,您应该在 addCar 中进行一些检查,以免超出 cars 数组。
编辑:
代码还有一些其他问题 - 例如,“d = Dealer();”创建一个新的 Dealer 并覆盖您通过引用 addCars 传递的经销商,这似乎不是您想要做的。
尝试向构造函数/析构函数添加一些额外的跟踪,以验证您认为正在调用的构造函数实际上是 - 看起来 Dealer() 应该使用您指定的默认参数调用构造函数,但如果不是,它就会获取默认构造函数。
You never initialize numCars - it contains some value from the heap which is almost definitely non-zero. This causes you to read beyond the end of the cars array and into inaccessible memory. You should set numCars to 0 in your constructor.
On top of this, you should have some checks in addCar so that you don't overrun the cars array.
EDIT:
There are some other issues with the code - for instance, "d = Dealer();" creates a new Dealer and overwrites the one you pass by reference to addCars which doesn't seem to be what you want to do.
Try adding some additional tracing to the constructor/destructors to verify that the constructors you think are being called actually are - it appears that Dealer() should be invoking the constructor with a default argument you specified, but if not it is getting the default constructor.
您没有在任何地方初始化
numCars
,您应该将其设置为 0:您必须使用原始指针吗?为什么不把它包装起来并使用 std::vector 来代替呢?
You're not initializing
numCars
anywhere, you should set it to 0:Do you have to use raw pointers? Why not wrap it up and use
std::vector
instead?上面的代码中没有任何内容初始化 Dealer::numCars。因此它可以是任何随机垃圾。
Nothing in the above code initializes Dealer::numCars. It can therefore be any random garbage.
也许我没有看到它,但你最初在哪里设置 numCars ?
Maybe I'm not seeing it but where do you initially set numCars?
对我来说,这看起来像是内存泄漏,因为您没有释放 cars 指针所持有的先前内存:
并且此代码确实应该防止溢出情况:
通过这样做:
This looks like a memory leak to me since, you don't release the previous memory held by the cars pointer:
and this code should really should guard against the overflow condition:
by doing something like this:
从发布的代码中我没有看到任何问题。可能问题出在其他地方?
也许您可以尝试以下操作:
将数组更改为向量并尝试使用 at() 捕获 out_of_range 异常。
像这样:
I don't see any problems from the posted code. May be problem is elsewhere ?
Probably you can try following:
change arrays to vector and try using at() to catch out_of_range exception.
something like: