[英]Segmentation fault when using vectors in the class and constructor
I was doing a list of programming projects, and this project is to make a 15 puzzle (slide puzzle).我在做一个编程项目的清单,而这个项目是做一个15拼图(slide拼图)。 I was working on the project when I hit a small roadblock.
当我遇到一个小障碍时,我正在研究这个项目。
My code compiles just fine, but when I run it, I get a segmentation fault at line 12: pos[0] = x;
我的代码编译得很好,但是当我运行它时,在第 12 行出现分段错误:
pos[0] = x;
#include <iostream>
#include <vector>
#include <stdlib.h>
#include <time.h>
using namespace std;
class Tile{
private:
vector<int> pos;
int value;
public:
Tile(int x, int y, int value_){
pos[0] = x;
pos[1] = y;
value = value_;
}
~Tile(){}
int getPos(int a){return pos[a];}
void setPos(int a, int b){pos[a] = b;}
};
int main(){
Tile tile1(1, 2, 10);
Tile* t1;
t1 = &tile1;
// returns position "x"
cout << t1->getPos(0);
return 0;
}
I mean, I could just do the whole project without having to use vectors/arrays to handle the position, but I do still want to know, for my own understanding in the future, why this doesn't work.我的意思是,我可以完成整个项目而不必使用向量/数组来处理位置,但我仍然想知道,为了我将来的理解,为什么这不起作用。
Based on the debug that I ran, the program is having trouble initializing the value of the pos[] vector.根据我运行的调试,程序在初始化 pos[] 向量的值时遇到问题。
Another issue: probably related, I tried setting the size of the vector when it was instantiated.另一个问题:可能相关,我尝试在实例化向量时设置向量的大小。
vector<int> pos(2);
But then I get the debug error:但是后来我得到了调试错误:
error: expected identifier before numeric constant
Not sure whats going on here.不知道这里发生了什么。 I've tried a bunch of different things but I can't seem to figure out why my vectors don't work inside of classes.
我尝试了很多不同的东西,但我似乎无法弄清楚为什么我的向量在类中不起作用。
I'm sure there are a hundred ways I could have done this little piece better, and I would love to know how you would have fixed it, but I also need to know what is wrong, specifically in the context of what I have written and tried.我确信有一百种方法我可以把这个小作品做得更好,我很想知道你会如何修复它,但我也需要知道什么是错的,特别是在我写的内容的背景下并尝试过。
Thanks.谢谢。
I tried setting the size of the vector when it was instantiated.
我尝试在实例化时设置向量的大小。
vector<int> pos(2);
But then I get the debug error:
但是后来我得到了调试错误:
error: expected identifier before numeric constant
That's a compilation error, not a debug error.那是编译错误,而不是调试错误。
You can't initialise members like that.你不能像那样初始化成员。 However, you can (and should) initialise them using the parent constructor:
但是,您可以(并且应该)使用父构造函数初始化它们:
Tile(int x, int y, int value_)
: pos(2)
{
pos[0] = x;
pos[1] = y;
value = value_;
}
Currently you're just leaving your vector empty then accessing (and writing to!) elements that don't exist.目前,您只是将向量留空,然后访问(并写入!)不存在的元素。
You really don't want a vector for this, anyway: that's a lot of dynamic allocation.无论如何,你真的不想要一个向量:那是很多动态分配。 How about a nice array?
一个漂亮的数组怎么样? Or just two
int
s.或者只是两个
int
。
As mentioned in other answers, your vector is empty and your code is attempting to assign non-existent elements.正如其他答案中提到的,您的向量为空,您的代码试图分配不存在的元素。
The solution is to always use initialisers instead of assignment.解决方案是始终使用初始化程序而不是赋值。 Rewrite your constructor as follows:
重写你的构造函数如下:
Tile(int x, int y, int value) :
pos{x, y},
value{value} {}
Note that the constructor body is now empty .请注意,构造函数体现在是空的。 All initialisation happens where it should — in the initialiser list.
所有初始化都发生在它应该发生的地方——在初始化列表中。
Apart from that, your class does not need an explicitly defined destructor;除此之外,您的类不需要显式定义的析构函数; the default destructor works just fine.
默认的析构函数工作得很好。
There are other issues with this class — for instance, what happens when the user does tile.setPos(3, 4)
?这个类还有其他问题——例如,当用户执行
tile.setPos(3, 4)
时会发生什么? A rule of thumb of good API design is to make it impossible to misuse the API.良好 API 设计的一个经验法则是避免滥用 API。
Here's how I would write your Tile
class instead:下面是我将如何编写您的
Tile
类:
struct Tile {
int x;
int y;
int value;
Tile(int x, int y, int value) : x{x}, y{y}, value{value} {}
};
The getter and setter in your case wasn't really doing any meaningful work.你的情况下的 getter 和 setter 并没有真正做任何有意义的工作。 There's an argument to be made to hide all data members behind accessors to future-proof access control.
有一个论点将所有数据成员隐藏在访问者后面,以实现面向未来的访问控制。 I'm no longer convinced this is actually useful but just in case, here's a solution with that, too:
我不再相信这实际上很有用,但以防万一,这里也有一个解决方案:
class Tile {
int x_;
int y_;
int value_;
public:
Tile(int x, int y, int value) : x_{x}, y_{y}, value_{value} {}
int x() const { return x; }
int& x() { return x; }
int y() const { return y; }
int& y() { return y; }
int value() const { return value; }
};
This makes x
and y
readable and writable (via assignment: tx() = 42;
), and value
only readable.这使得
x
和y
可读和可写(通过赋值: tx() = 42;
),并且value
仅可读。 Other APIs are possible, with different sets of trade-offs.其他 API 也是可能的,但要进行不同的权衡。 The important thing is to be consistent.
重要的是要保持一致。
Your constructor doesn't set the size, so when you try to access/modify its contents, you are probably getting the exception.您的构造函数没有设置大小,因此当您尝试访问/修改其内容时,您可能会遇到异常。
Tile(int x, int y, int value_) : pos(2) {
pos[0] = x;
pos[1] = y;
value = value_;
}
You can use the initialization list of the constructor to call the vector
's constructor, as in the code above.您可以使用构造函数的初始化列表来调用
vector
的构造函数,如上面的代码所示。
There are couple of issue in the given code, which I have resolved and added comment in the code.给定的代码中有几个问题,我已经解决并在代码中添加了注释。
Issue in setPos
and getPos
might raise segmentation fault must be handle. setPos
和getPos
可能会引起必须处理的分段错误。
Added checks for the same.添加了相同的检查。
#include <iostream>
#include <vector>
#include <stdlib.h>
#include <time.h>
using namespace std;
class Tile{
private:
vector<int> pos;
int value;
public:
Tile(int x, int y, int value_){
pos.push_back(x); // this is equivalent to pos[0] = x, in this case
pos.push_back(y); // this is equivalent to pos[0] = y, in this case
value = value_;
}
~Tile(){}
int getPos(int a){
if(a >= pos.size()){
return -1; // if a is greater than size then pos[a] will raise the segmentation fault
}
return pos[a];
}
void setPos(int a, int b){
if(a >= pos.size()){
pos.resize(a+1); // to avoid segmentation fault, we are increasing the size if the given index is higher
// resize initialise the value with 0 as default value.
}
pos[a] = b;
}
};
int main(){
Tile tile1(1, 2, 10);
Tile* t1;
t1 = &tile1;
// returns position "x"
cout << t1->getPos(0);
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.