我可以被认为是编程的初学者。我正在尝试用C ++编写一个可以保存多维数据的类(例如MxN矩阵)。我不想通过矢量矢量的方式来做。我写了下面这段代码,但是当我用g ++编译它时,我得到了分段错误:11错误。另一方面,当我尝试使用Xcode编译它时,它在行
给出“线程1:EXC_BAD_ACCESS(代码= 1,地址= 0x0)”particles[i].x = x0 + R*cos(theta*i);
所以,我想我得到了一种与为对象分配值相关的内存错误。
在C ++中是否允许使用这种语法:
particles_old[i].x = particles[i].x;
或者我可以这样:
// say A is a class with x a vector this time, instead of a double data.
// in nested for loops
vector<A> B;
B[i].x[j] = some value;
我知道它有点模糊,但从语法的角度来看它至少是正确的吗?
#include <iostream>
#include <cmath>
#include <fstream>
#include <string>
#include <vector>
#include <random>
using namespace std;
class Particle{
public:
double x; // x position
double y; // y position
double vx; // velocity in the x direction
double vy; // velocity in the y direction
double Fx; // force in the x direction
double Fy; // force in the y direction
// Default constructor
Particle()
: x(0.0),y(0.0),vx(0.0),vy(0.0),Fx(0.0),Fy(0.0){
}
};
int main() {
const float pi = 3.14;
int N = 30; // Number of 'particles' that make up the cell
float theta = 2*pi/N; // Angle between two particles in radians
float x0 = 0; // Center of the cell [x]
float y0 = 0; // Center of the cell [y]
float R = 5e-6; // Radius of the cell
vector<Particle> particles; // particles
// Assigning the initial points onto the circle
for(int i = 0; i < N; i++) {
particles[i].x = x0 + R*cos(theta*i);
particles[i].y = y0 + R*sin(theta*i);
}
float k = 4.3e-7; // Spring constant connecting the particles
float m = 2e-8; // Mass of the particles
// Calculating the initial spring force between the particles on the cell
particles[0].Fx = -k*(particles[1].x - particles[N].x);
particles[0].Fy = -k*(particles[1].y - particles[N].y);
for(int i = 1; i < N-1; i++) {
particles[i].Fx = -k*(particles[i+1].x - particles[i-1].x);
particles[i].Fy = -k*(particles[i+1].y - particles[i-1].y);
}
particles[N].Fx = -k*(particles[0].x - particles[N-1].x);
particles[N].Fy = -k*(particles[0].y - particles[N-1].y);
// Initial velocities are given to each particle randomly from a Gaussian distribution
random_device rdx; // Seed
default_random_engine generatorx(rdx()); // Default random number generator
random_device rdy; // Seed
default_random_engine generatory(rdy()); // Default random number generator
normal_distribution<float> distributionx(0,1); // Gaussian distribution with 0 mean and 1 variance
normal_distribution<float> distributiony(0,1); // Gaussian distribution with 0 mean and 1 variance
for(int i = 0; i < N; i++) {
float xnumber = distributionx(generatorx);
float ynumber = distributiony(generatory);
particles[i].vx = xnumber;
particles[i].vy = ynumber;
}
// Molecular dynamics simulation with velocity Verlet algorithm
// 'Old' variables
vector<Particle> particles_old;
for(int i = 0; i < N; i++) {
particles_old[i].x = particles[i].x;
particles_old[i].y = particles[i].y;
particles_old[i].vx = particles[i].vx;
particles_old[i].vy = particles[i].vy;
particles_old[i].Fx = particles[i].Fx;
particles_old[i].Fy = particles[i].Fy;
}
// Sampling variables
int sampleFreq = 2;
int sampleCounter = 0;
// MD variables
float dt = 1e-7;
float dt2 = dt*dt;
float m2 = 2*m;
int MdS = 1e+4; // Molecular dynamics step number
// MD
for(int j = 0; j < MdS; j++) {
// Update x
for(int i = 0; i < N; i++) {
particles[i].x = particles_old[i].x + dt*particles_old[i].vx + dt2*particles_old[i].Fx/m2;
particles[i].y = particles_old[i].y + dt*particles_old[i].vy + dt2*particles_old[i].Fy/m2;
}
// Update F
particles[0].Fx = -k*(particles[1].x - particles[N].x);
particles[0].Fy = -k*(particles[1].y - particles[N].y);
for(int i = 1; i < N-1; i++) {
particles[i].Fx = -k*(particles[i+1].x - particles[i-1].x);
particles[i].Fy = -k*(particles[i+1].y - particles[i-1].y);
}
particles[N].Fx = -k*(particles[0].x - particles[N-1].x);
particles[N].Fy = -k*(particles[0].y - particles[N-1].y);
// Update v
for(int i = 0; i < N; i++) {
particles[i].vx = particles_old[i].vx + dt*(particles_old[i].Fx + particles[i].Fx)/m2;
particles[i].vy = particles_old[i].vy + dt*(particles_old[i].Fy + particles[i].Fy)/m2;
}
// Copy new variables to old variables
for(int i = 0; i < N; i++) {
particles_old[i].x = particles[i].x;
particles_old[i].y = particles[i].y;
particles_old[i].vx = particles[i].vx;
particles_old[i].vy = particles[i].vy;
particles_old[i].Fx = particles[i].Fx;
particles_old[i].Fy = particles[i].Fy;
}
}
}
提前致谢。
答案 0 :(得分:2)
// Assigning the initial points onto the circle
for(int i = 0; i < N; i++) {
particles[i].x = x0 + R*cos(theta*i);
particles[i].y = y0 + R*sin(theta*i);
}
在您输入该循环时,您的矢量为空。然后,您尝试使用operator[]
访问其中的元素。如果您查看有关std::vector operator[]的信息,请说明以下内容:
&#34;便携式程序永远不应该使用超出范围的参数n来调用此函数,因为这会导致未定义的行为。&#34;
你正是这样做的,访问一个超出范围的元素,在这种情况下,未定义的行为是崩溃。
将该循环更改为:
// Assigning the initial points onto the circle
for(int i = 0; i < N; i++) {
// Create and initialize a new particle
Particle newParticle;
newParticle.x = x0 + R*cos(theta*i);
newParticle.y = y0 + R*sin(theta*i);
// add it to the vector
particles.push_back(newParticle);
}
为您明确创建新的Particle
,然后使用std::vector
方法将其添加到.push_back()
。
注意这两行:
particles[N].Fx = -k*(particles[0].x - particles[N-1].x);
particles[N].Fy = -k*(particles[0].y - particles[N-1].y);
可能会因为完全相同的原因而崩溃,因为在那时你已经完全填充了[0 .. N-1],你还没有在插槽N中放置一个元素。我会留给你解决这个问题,因为解决方案与for循环完全相同。
答案 1 :(得分:2)
嘿,您需要在将粒子添加到列表中时初始化粒子,例如
for (int i = 0; i < N+1; i++) { // You are accessing [N] directly in your code..
Particle p;
p.x = x0 + R*cos(theta*i);
p.y = y0 + R*sin(theta*i);
particles.push_back(p);
}
我将代码简化了一下,因为你直接使用[N] +1就在那里,你应该在代码中改为[N-1],否则你将超出你的向量。
你将粒子推向矢量,在矢量的末尾,记住你的矢量是空的!我相信这可以做得更好,说实话我在这里有点生疏我的自我:)拿起我的“婴儿语言”和那里已经实现的所有很酷的功能。
我不确定我是否按照你的问题,但如果你想看看简单的2维数组there is a rather usefull post here at SO。
无论如何,我希望它可以帮助你。答案 2 :(得分:2)
你已经有两个很好的答案了。这是另一种变体:
如果您事先知道矢量的大小,您可以按如下方式定义:
vector<Particle> particles(N); // create a vector with N particles default initialized.
其余的代码应该可以工作,因为粒子[i]将引用已经存在的粒子。
是的,old_particles = particles;
将复制整个矢量。无需循环中的元素copyelement。
答案 3 :(得分:1)
除了其他答案,我也会这样做
在创建粒子之前 particles.reserve(N);
(或N+1
),因此向量不必在循环期间重新分配内存
或甚至将particles
声明为vector<Particle> particles(N);
(或再次N+1
),因此向量已经填充了默认初始化粒子,您只需像以前一样分配它们的值。 / p>
选择N
或N+1
取决于行
particles[0].Fx = -k*(particles[1].x - particles[N].x);
您似乎在这里访问N
元素,如果它不是拼写错误,则矢量大小应为N + 1
。