在类和构造函数中使用向量时出现分段错误



我正在做一个编程项目列表,这个项目是制作一个 15 个拼图(幻灯片拼图(。当我遇到一个小障碍时,我正在做这个项目。

我的代码编译得很好,但是当我运行它时,我在第 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;
}

我的意思是,我可以只做整个项目,而不必使用向量/数组来处理位置,但我仍然想知道,为了我将来的理解,为什么这不起作用。

根据我运行的调试,程序在初始化 pos[] 向量的值时遇到问题。

另一个问题:可能相关,我尝试在实例化时设置矢量的大小。

vector<int> pos(2);

但是后来我收到调试错误:

error: expected identifier before numeric constant

不知道这里发生了什么。我已经尝试了很多不同的东西,但我似乎无法弄清楚为什么我的向量在类中不起作用。

我敢肯定,有一百种方法可以把这个小文章做得更好,我很想知道你会如何修复它,但我也需要知道哪里出了问题,特别是在我所写和尝试过的背景下。

谢谢。

我尝试在实例化时设置向量的大小。

vector<int> pos(2);

但是后来我收到调试错误:

error: expected identifier before numeric constant

这是编译错误,而不是调试错误。

您不能像这样初始化成员。但是,您可以(并且应该(使用父构造函数初始化它们:

Tile(int x, int y, int value_)
: pos(2)
{
pos[0] = x;
pos[1] = y;
value = value_;
}

目前,您只是将向量留空,然后访问(并写入!(不存在的元素。

无论如何,你真的不想要一个向量:这是很多动态分配。一个漂亮的阵列怎么样?或者只是两个int秒。

如其他答案所述,您的向量为空,并且您的代码正在尝试分配不存在的元素。

解决方案是始终使用初始化器而不是赋值。重写构造函数,如下所示:

Tile(int x, int y, int value) :
pos{x, y},
value{value} {}

请注意,构造函数主体现在为。所有初始化都发生在它应该发生的地方——在初始化器列表中。

除此之外,你的类不需要显式定义的析构函数;默认析构函数工作得很好。

此类还有其他问题 - 例如,当用户执行tile.setPos(3, 4)时会发生什么?良好的 API 设计的经验法则是使滥用 API 的可能性变得不可能。

以下是我将如何编写您的Tile类:

struct Tile {
int x;
int y;
int value;
Tile(int x, int y, int value) : x{x}, y{y}, value{value} {}
};

在你的案例中,getter 和 setter 并没有真正做任何有意义的工作。有一个论点是将所有数据成员隐藏在访问者后面,以实现面向未来的访问控制。我不再相信这实际上有用,但以防万一,这也是一个解决方案:

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; }
};

这使得xy可读和可写(通过赋值:t.x() = 42;(,并且value只能读取。其他 API 是可能的,但需要权衡。重要的是保持一致。

构造函数没有设置大小,因此当您尝试访问/修改其内容时,您可能会遇到异常。

Tile(int x, int y, int value_) : pos(2) {
pos[0] = x;
pos[1] = y;
value = value_;
}

你可以使用构造函数的初始化列表来调用vector的构造函数,如上面的代码所示。

给定的代码中有几个问题,我已经解决了这些问题并在代码中添加了注释。

必须处理setPosgetPos中可能引发分段错误的问题。

添加了相同的检查。

#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;
}

相关内容

  • 没有找到相关文章

最新更新