当我从常量引用调用方法时,程序失败
Program fails when I call a method from constant reference
所以,我有一个令牌类:令牌.h
class Token {
std::string name; // token name
int frequency;//frequency
Vector lines;//lines where the token is present
public:
//explanations for the methods in the Token.cpp
Token(std::string tokenname, int linenumber);
virtual ~Token();
const Vector getLines() const;
};
#endif /* TOKEN_H_ */
令牌 cpp
Token::Token(string tokenname, int linenumber) {
// TODO Auto-generated constructor stub
name = tokenname;
frequency=1;
lines.push_back(linenumber);
}
Token::~Token() {
// TODO Auto-generated destructor stub
}
std::string Token::getName() const{
return name;
}
int Token::getFrequency() const{
return frequency;
}
const Vector Token::getLines() const{
const Vector vec = lines;
return lines;
}
程序失败,当我将其传递给列表类的插入方法
class List {
private:
class Node {
public:
Token data;
Node* next;
Node(const Token &dataItem, Node* nextptr);
~Node();
};
Node* first;
int length;
public:
List();
virtual ~List();
void insert(const Token &t);
};
列表.cpp:
List::Node::Node(const Token &dataItem, Node* nextptr): data(dataItem), next(nextptr){
}
List::Node::~Node(){
cout<<"dead"<<endl;
}
List::List() {
// TODO Auto-generated constructor stub
length = 0;
first = nullptr;
}
List::~List() {
// TODO Auto-generated destructor stub
Node* temp = first;
Node* newtmp;
while(temp->next != nullptr){
newtmp = temp->next;
delete temp;
temp = newtmp;
}
}
const int List::size(){
return length;
}
void List::insert (const Token &t){
Vector dammit = t.getLines();
}
我发现了插入中的哪一行(Vector dammit = t.getLines(((,所以我就这样离开了。它给了我这个错误消息:
如果你想双重释放或损坏(快速顶部(:0x0000000000c34040***
运行,这里有一些来自主文件的东西:
int main() {
// cout<<"tokens are here"<<endl;
//
Token hit("aca", 1);
Token hit2("ui", 2);
Token hit1("111", 3);
List list;
list.insert(hit);
list.insert(hit2);
list.insert(hit1);
}
向量类:
class Vector {
int* store;
int capacity;
int next_index;
public:
Vector();
Vector(int initial_size);
Vector(const Vector &v);
virtual ~Vector();
void push_back(int item);
int pop_back();
const int size() const;
void resize();
void operator =(const Vector &v);
int& operator[] (int k);
const int& operator[] (int k) const;
friend std::ostream& operator<<(std::ostream& os, const Vector& v);
};
Vector::Vector() {
// TODO Auto-generated constructor stub
store = new int [1];
capacity = 1;
next_index = 0;
}
Vector::Vector(int initial_size){
store = new int [initial_size];
capacity = initial_size;
next_index = 0;
}
Vector::Vector(const Vector &v){
store = v.store;
capacity = v.capacity;
next_index = v.next_index;
}
Vector::~Vector() {
// TODO Auto-generated destructor stub
delete[] store;
}
void Vector::resize(){
std::cout<<"in resize"<<std::endl;
std::cout<<capacity<<std::endl;
int length = capacity;
capacity+=100;
int* tempArray;
tempArray = new int[capacity];
for (int i=0; i<length; i++){
tempArray[i] = store[i];
}
if (length>1)
delete[] store;
std::cout<<"finish re4size"<<std::endl;
store = tempArray;
}
void Vector::push_back(int item){
if(next_index >= capacity)
this->resize();
store[next_index] =item;
next_index++;
}
int Vector::pop_back(){
next_index = next_index-1;
int last = store[next_index];
return last;
}
void Vector::operator =(const Vector &v){
//delete[] store;
store = v.store;
capacity = v.capacity;
next_index = v.next_index;
}
const int Vector::size() const{
return next_index-1;
}
int& Vector::operator[] (int k){
//assert((k<next_index)&(k>=0));
return store[k];
}
const int& Vector::operator[] (int k) const{
//assert((k<next_index)&(k>=0));
return store[k];
}
ostream& operator<<(ostream& os, const Vector& v)
{
for(int i=0; i<=v.size(); i++){
os << v[i]<< ' ';
}
return os;
}
in
Vector::Vector(const Vector &v){
store = v.store;
capacity = v.capacity;
next_index = v.next_index;
}
现在,您有两个指向同一int* store;
的向量
在
void Vector::operator =(const Vector &v){
//delete[] store;
store = v.store;
capacity = v.capacity;
next_index = v.next_index;
}
你做同样的事情。
当您致电时
const Vector Token::getLines() const{
const Vector vec = lines;
return lines;
}
vec = lines
使用复制构造函数。您现在有指向同一商店的 vec 和行。
您返回行的副本,这将再次触发复制构造函数。第三个对象现在指向存储。
堆栈展开时,本地定义的vec
将被销毁。 ~Vector
delete
的商店。现在,您有两个对象指向同一个已解除分配的存储。
噗嗤! 一旦你尝试用这些向量中的任何一个做很多其他事情。看起来返回的 Vector 的破坏首先命中并导致析构函数重新删除存储。
您需要为新存储分配存储,然后在 = 运算符和复制构造函数中将源存储的内容复制到新存储中。
Vector::Vector(const Vector &v){
capacity = v.capacity;
store=new int[capacity];
for (size_t index; index < capacity; index++)
{
store[index] = v.store[index];
}
next_index = v.next_index;
}
和
Vector & Vector::operator =(const Vector &v){
delete[] store;
capacity = v.capacity;
store=new int[capacity];
for (size_t index; index < capacity; index++)
{
store[index] = v.store[index];
}
next_index = v.next_index;
}
std::copy
可用于代替 C++11 中的 for 循环。也可以使用旧的memcpy
,但这只是因为存储是一种原始数据类型。
在我编辑时,感谢 Jarod42,还有一个小调整:
const Vector & Token::getLines() const{ //note the return of a reference. This avoids
// making a copy of lines unless the caller really
// wants a copy.
// const Vector vec = lines; don't need to do this. lines is const-ified by the
// const on the return type of the function
return lines;
}
此错误与调用具有常量引用的方法无关,而是函数 getLines()
。例如,如果您采用hit1
并直接调用函数getLines()
,它仍然会崩溃。问题在于Token
如何具有堆栈分配的属性Vector
,而堆栈分配属性又具有int *
属性。这不一定是问题,但根据您实现这些类的方式,它可能会导致内存冲突。
如果你想继续使用你的getLine()
并且不能使用<vector>
库,你可以将Token
的lines
属性更改为Vector *
,并相应地更改所有其他语法。还要记住初始化你的指针lines
内存,否则它会崩溃。
但是,如果没有必要,我宁愿使用尽可能少的动态分配内存。就像另一位用户所说,在while(temp->next != nullptr)
之前,您应该有一个条件if(temp != nullptr )
- libprotobuf 检查在 Mac OS 上执行程序时失败
- QDateTime::toString() 在退出处理程序中使用时失败
- 为什么我的Qt程序在断言失败后继续运行?
- 每次b/c程序无法加载级联时,使用harr级联的人脸识别都会失败
- C++ 错误的分配应用程序失败
- MXE Qt5 应用程序构建在 Docker 容器中失败
- 激活上下文生成失败,依赖程序集,并行,事件 ID 33
- 用户创建程序失败
- 在 Windows 7 的 CodeBlocks 16.01 中构建 glfw3 程序失败
- 添加大数字C++-初始化程序失败
- 通过Visual Studio运行程序会导致程序失败
- 自定义矢量类模板初始化程序失败
- 在Mac OSX上为i386目标构建Apache Thrift应用程序失败
- Crypto++导致应用程序失败
- Perl 5.14源代码-示例程序失败
- QtCreator:启动程序失败.路径或权限错误
- c++应用程序失败-没有错误
- 处理程序失败后该怎么做
- 程序失败.共享 Ptr 矢量 c++
- 当我从常量引用调用方法时,程序失败