结构问题中的数组 [英] Array in structure issue
问题描述
各位大家好。我正在尝试创建描述具有一些位置和速度的粒子的结构。我正在做以下事情:
Hello everybody. I'm trying to create the structure describing particles with some positions and velocity. I'm doing the following:
#define SIZE 1000000
#define nx 1000
typedef struct Species{
double x[SIZE];
double y[SIZE];
double vx[SIZE];
double vy[SIZE];
double vz[SIZE];
double dens[nx];
double charge;
double mass;
long int num; //actual number of particles
double QtoM;
double sw; //weight of macroparticles
char *bc_l;
char *bc_r;
} species;
我尝试过:
我填充main函数中的所有数组。当我编译代码时,我没有看到任何警告或错误消息。但是,当我运行它时,我看到消息堆栈溢出。据我所知,问题是SIZE = 1000000,因为代码在我使用SIZE = 10000时运行。任何人都可以帮我吗?
谢谢。可以,我应该改变我的方法吗?
What I have tried:
I fill all arrays within the main function. When I compile the code, I don't see any warning or error message. But, when I run it, I see the message "stack overflow". As I understand correctly, the problem is with SIZE=1000000 because the code runs when I use SIZE=10000. Can anybody help me with this?
Thanks.May be, I should change my approach?
推荐答案
你的结构物种有五个成员,大小sizeof(double)* SIZE
。对于X86系统,当SIZE = 1,000,000时,该系统可以处理大约38 MB的数据。这意味着,对于您声明的每个 struct Species ,您在堆栈上使用了那么多空间 。
我可以想到4个选项:
1)修改运行时环境以提供更大的堆栈
2)如果你只有一个struct Species
,您可以考虑全局声明它。有很多关于全局变量的文献以及何时,何地,为什么或为什么不是,所以你应该在决定走这条路之前先研究一下
3)在堆上分配例如
Your struct Species has five members of sizesizeof(double) * SIZE
. For an X86 system that works out to about 38 MB of data when SIZE = 1,000,000. That means that for every struct Species you declare, you are using that much space on the stack.
I can think of 4 options:
1) modify your run-time environment to provide a larger stack
2) If you only have one instance ofstruct Species
, you might consider declaring it globally. There's a whole lot of literature about global variables and when, where, why or why-not, so you should look into that before deciding to go that route
3) allocate on the heap e.g.
struct Species *s;
s = malloc(sizeof *s);
4)你有一个成员变量 species.num
。这似乎是您要跟踪的实际项目数。如果从某个地方读取,例如数据库或文件,那么你可以最小化你的内存使用我单独分配大数组,例如
4) you have a member variable species.num
. This seems to be the actual number of items you're tracking. If that's read in from somewhere, e.g a database or file, then you can minimize your memory use my allocating the large arrays individually e.g.
typedef struct Species {
double *x;
double *y;
// ? are we missing a double *z; here?
double *vx;
double *vy;
double *vz;
size_t num; // actual number of particles n.b. changed to size_t
...
}species;
...
int main()
{
species sp;
sp.num = get_num_particles(); // determine number of particles in the system
sp.x = malloc(num * sizeof *sp.x);
sp.y = malloc(num *sizeof *sp.y);
...
sp.vz = malloc(num *sizeof *sp.z);
// do something interesting with sp
free(sp.x);
free(sp.y);
....
free(sp.vz);
return 0;
}
请注意,我们没有使用 sp.x = malloc(num * sizeof(double)
分配内存。使用 sp.x = malloc(num * sizeof * sp.x)
,如果我们将sp.x的类型更改为例如 long double
,我们不需要去查找我们alloc()sp.x的所有地方,并确保类型一致,这是由编译器为我们处理的。
Note that we're not using sp.x = malloc(num * sizeof(double)
to allocate memory. By using sp.x = malloc(num * sizeof *sp.x)
, if we change the type of sp.x to e.g. long double
, we don't then need to go and find all the places we alloc() sp.x and make sure the type agrees, that's handled for us by the compiler.
代码如下:
The code is the following:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
// --- physical constants:
#define boltzmann (1.38e-23)
#define eps0 (8.89e-12)
#define AMU (1.67e-27)
#define qe (1.6e-19)
#define me (9.11e-31)
#define mi (4.0*AMU)
#define PI (3.1415926)
#define sq(x) (x*x)
#define SIZE 100000 //the largest number of particles
#define NP0 9000
#define nx 1000 //number of grid cells
#define time_step (1e-12)
#define pw (1e7) //weight of macroparticles
#define Scath (1e-4) //cathode surface area
#define Ucathode (-100.0)
#define ca_gap (1e-2)
long int seed;
long int i_max = 1000;
typedef struct Species{
double x[SIZE];
//double y[SIZE];
double vx[SIZE];
double vy[SIZE];
//double vz[SIZE];
double dens[nx];
double charge;
double mass;
long int num; //actual number of particles
double QtoM;
double sw; //weight of macroparticles
char *bc_l;
char *bc_r;
} species;
int main(void){
// --- define species:
species electrons;
electrons.charge = -qe;
electrons.mass = me;
electrons.num = NP0;
electrons.QtoM = electrons.charge/electrons.mass;
electrons.bc_l = "absorb";
electrons.bc_r = "absorb";
electrons.sw = pw;
// --- seed initial plasma:
seed = getpid();
for (int j = 0; j < electrons.num; j++){
electrons.x[j] = 0.0;
electrons.vx[j] = 0.0;
}
}</string.h></unistd.h></stdlib.h></math.h></stdio.h>
我会采用另一种方式定义仅适用于单一物种的结构,而不是动态创建数组。如果你有全局设置,我会使用另一个结构来保存它们。
I would go another way and define a "single specie only" struct and than dynamicly create an array. If you have global settings I would use another struct to hold them.
typedef struct SingleSpecie{
double x;
double y;
double vx;
double vy;
double vz;
double dens;
double charge;
double mass;
//long int num; //actual number of particles - doesnt belong her
double QtoM;
double sw; //weight of macroparticles
char *bc_l;
char *bc_r;
} specie;
//create array
SingleSpecie* allCreatures = malloc( myCount * sizeof(SingleSpecie) );
这篇关于结构问题中的数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!