我试图创建一个三角形网格,以编写有限元分析的代码。我知道已经编写了这样的软件,但这是针对一个类项目的。
我尝试做的是将区域划分为均匀间隔的节点(网格点)。每个节点有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;
}
答案 0 :(得分:1)
在Node::Node
,
vector<Triangle*> Triangles;
Node() : Triangles(6) {}
您只是将Triangles
初始化为vector
大小6
。这不会为您提供有效的内存位置 - Triangle*
中的Triangles
需要使用new
进行分配。
通常,您不需要vector<Triangle*>
。只需使用vector<Triangle>
代替。
答案 1 :(得分:0)
该程序的第二个版本避免了段错误,但没有解决 首先应该解决使用指针的问题。
首先,虽然这是您的问题的偶然因素,
我强烈建议写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
,
对于Node
应该连接的每个Triangle
,
您需要在Triangle
的{{1}}列表中插入triangle
您需要将Node
插入Node
的{{1}}列表中。
既然你总是成对地完成这些作业,那么拥有一个作品是值得的
两个函数调用。为了使事情更方便和
不容易出错, 函数被成员函数调用三次
vertex
的{{1}}个参数,每个参数Triangle
一个
Triangle
将连接到。
如果这还不够清楚,请尝试绘制一些Node*
的图表
对象和Node
对象,指针箭头连接它们
他们应该联系的方式。无论你写什么都必须
创建一个数据结构,所有指针都正确链接。