访问存储在矢量中的指针的值
Accessing value of pointer stored in vector
我正在尝试创建一个三角形网格来编写有限元分析的代码。我知道已经编写了软件来做到这一点,但这是为类项目准备的。
我正在尝试做的是将该区域划分为均匀分布的节点(网格点)。每个节点都有 6 个三角形连接到它,需要在计算中使用。为了方便起见,我创建了两个结构,一个用于节点,一个用于三角形。
下面,我有一个我试图在我的代码中实现的内容的最小工作示例。但是,此代码在将 x,y 值分配给顶点的行上收到分段错误。在 gdb 中生成的错误指出:
With using vectors (as per the minimum working example)
----------------------------
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400f90 in std::vector<Node*, std::allocator<Node*> >::operator[] (this=0x0, __n=0)
at /usr/include/c++/4.8/bits/stl_vector.h:771
771 { return *(this->_M_impl._M_start + __n); }
// Running backtrace
(gdb) bt
#0 0x0000000000400f90 in std::vector<Node*, std::allocator<Node*> >::operator[] (this=0x0, __n=0)
at /usr/include/c++/4.8/bits/stl_vector.h:771
#1 0x0000000000400a87 in main () at minimumexample.cpp:28
----------------------------
我不知道如何弄清楚这一点。如果我使用数组代替向量,则会产生类似的错误,所以我认为这只是向量类的问题吗?
With arrays instead of vectors
----------------------------
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400929 in main () at minimumexample.cpp:28
28 MyGrid[0].Triangles[0]->vertex[0]->x = 0;
// Running backtrace
(gdb) bt
#0 0x0000000000400929 in main () at minimumexample.cpp:28
----------------------------
下面是我正在尝试做的事情的最小工作示例。我不确定为什么我会收到越界错误,因为我根本没有看到我在向量中越界的位置。
#include <iostream>
#include <vector>
using namespace std;
struct Triangle;
struct Node
{
double x;
double y;
vector<Triangle*> Triangles;
Node() : Triangles(6) {}
};
struct Triangle
{
vector<Node*> vertex;
Triangle() : vertex(3) {} // 3 vertices per triangle
};
int main()
{
int size = 10;
vector<Node> MyGrid(size);
double spacing = .25;
// The below code should create 3 vertices of the triangle with the
// three vertices of the triangle (x,y) defined as locations (0,0) for the
// first vertex, (1,0) for the second vertex, and (1,1) for the third.
MyGrid[0].Triangles[0]->vertex[0]->x = 0; // Line 28: Error here
MyGrid[0].Triangles[0]->vertex[0]->y = 0;
MyGrid[0].Triangles[0]->vertex[1]->x = 1;
MyGrid[0].Triangles[0]->vertex[1]->y = 0;
MyGrid[0].Triangles[0]->vertex[2]->x = 1;
MyGrid[0].Triangles[0]->vertex[2]->y = 1;
return 0;
}
对于遇到此问题的任何其他人,这是代码的工作版本:
#include <iostream>
#include <vector>
using namespace std;
struct Triangle;
struct Node
{
double x;
double y;
Triangle *Triangles;
};
struct Triangle
{
Node *vertex;
};
int main()
{
int size = 10;
vector<Node> MyGrid(size);
double spacing = .25;
// Allocate 6 Triangle objects into the variable Triangles
MyGrid[0].Triangles = new Triangle[6];
// Allocate 3 nodes for Triangles[0]'s vertex
MyGrid[0].Triangles[0].vertex = new Node[3];
MyGrid[0].Triangles[0].vertex[0].x = 0;
MyGrid[0].Triangles[0].vertex[0].y = 0;
MyGrid[0].Triangles[0].vertex[1].x = 1;
MyGrid[0].Triangles[0].vertex[1].y = 0;
MyGrid[0].Triangles[0].vertex[2].x = 1;
MyGrid[0].Triangles[0].vertex[2].y = 1;
return 0;
}
在Node::Node
中,
vector<Triangle*> Triangles;
Node() : Triangles(6) {}
您只需将Triangles
初始化为大小6
的vector
。这不会为您提供有效的内存位置 -Triangle*
的Triangles
需要使用new
进行分配。
通常,您不需要vector<Triangle*>
。只需改用vector<Triangle>
即可。
该程序的第二个版本避免了段错误,但没有解决 使用指针首先应该解决的问题。
首先,虽然这是你的问题附带的, 我强烈建议写Triangle* triangles
(注意小写t
)而不是Triangle* Triangles
,因此triangles
显然是一个变量名,而不是一个类名。
您现在遇到的问题是,如果您继续初始化 以这种方式MyGrid
的其他元素,每个 应该位于顶点的三个Node
对象 的网格三角形之一将创建 它自己的Triangle
对象来覆盖那个三角形。你最终会得到 三个Triangle
对象,你只需要一个,就不会有Triangle
,所有三个正确的Node
对象都链接到它。 此外,Node
没有一个反对任何Node* vertex
任何Triangle
的数组都在原始vector<Node> MyGrid
中, 而且它们都没有链接到任何Triangle
(甚至是链接Triangle
),更不用说它应该有的六个Triangle*
指针了。
你所拥有的甚至不是网格的开始, 它注定是"岛屿"的集合,每个岛屿一个MyGrid
的成员,每个人都与其他人完全隔离。
请注意,当您编写MyGrid[0].Triangles[0].vertex[0].x = 0
时, 如果所有对象都正确相互连接,则MyGrid[0].Triangles[0].vertex[0]
只是指向另一个Node
的指针, 大概是MyGrid
的成员(为什么要存储Node
对象 其他任何地方?),所以做同样事情的更直接的方法会 是确定这是MyGrid
的哪个成员,例如成员1
, 并改为写MyGrid[1].x = 0
。
实际上,类似的东西MyGrid[1].setCoordinates(0,0)
设置两者 同时使用 x 和 y 坐标将使程序更易于阅读 并且不太可能出错。
更好的策略可能是更改Node
和Triangle
的定义 回到以前的样子, 但这一次,在您创建Node
对象的向量之后, 对于每个Node
调用初始化其坐标的成员函数 (或初始化Node
构造函数中的坐标,然后push_back
到vector<Node>
); 然后开始创建Triangle
对象。对于您创建的每个Triangle
, 对于Triangle
应连接到的每个Node
, 您需要在该Node
的triangle
列表中插入Triangle
并且您需要将Node
插入该Triangle
的vertex
列表中。 由于您总是成对地完成这些作业,因此拥有一个单独的作业是值得的 同时执行这两项操作的函数调用。让事情变得更加方便和 不太容易出错,让成员函数调用该函数三次 的Triangle
,需要三个Node*
参数,每个参数对应一个Node
Triangle
是连接到。
如果这还不够清楚,请尝试绘制一些Triangle
的图表 对象和Node
对象,用指针箭头连接它们 它们应该连接的方式。无论你写什么都必须 创建一个正确链接所有这些指针的数据结构。
- 将一个类的方法指针存储到另一个类中
- 将字符指针存储到容器中
- 用指向文件的指针存储数据结构
- C++17:unique_ptr<char[]> 和 shared_ptr<char[] 之间的指针存储差异>
- 将指针存储到矢量时内存泄漏
- 指针存储字符串?
- 将指针存储到SQLITE3数据库中的类别抛出segfault
- 指向本地变量的指针存储在此变量范围之外
- 将模板化对象指针存储在矢量中并通过基类指针进行访问
- 如何将指针存储在实例变量中,该指针被声明为指向基类的指针
- 将指针或一系列指针存储在动态阵列中
- 当对象的指针存储在矢量中时,如何访问对象中的方法?
- 将从方法返回的原始指针存储到智能指针中
- 将指向参数个数可变的函数的指针存储在结构对象中
- 将指向const的指针存储到structs的向量中
- 一系列指针存储地址并以后打印
- 将指针存储在std :: unordered_map中的不同类型的类中
- 超级级别的方法称为super具有sub的str attr 实例在循环 实例中创建的方法是作为super的指针存储在向
- 使用字符指针存储整数
- 我们是否应该将指向类实例的智能指针存储在大型 std::vector 中以获得更好的性能?