DimaLevko Ответов: 3

Массив в структуре вопроса


Всем привет. Я пытаюсь создать структуру, описывающую частицы с некоторыми положениями и скоростью. Я делаю следующее:
#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;


Что я уже пробовал:

Я заполняю все массивы внутри основной функции. Когда я компилирую код, я не вижу никакого предупреждения или сообщения об ошибке. Но, когда я запускаю его, я вижу сообщение "переполнение стека". Как я правильно понимаю, проблема заключается в размере=1000000, потому что код запускается, когда я использую размер=10000. Кто-нибудь может мне помочь с этим?

Спасибо.Может быть, мне стоит изменить свой подход?

Patrice T

вы забыли показать код.
Попробуйте показать достаточно кода, чтобы мы могли воспроизвести ошибку.

[no name]

1

3 Ответов

Рейтинг:
27

k5054

Ваш структурные виды имеет пять членов размера sizeof(double) * SIZE Для системы X86, которая работает примерно до 38 МБ данных при размере = 1 000 000. Это означает, что для каждого структурные виды вы заявляете, что используете так много места в стеке.

Я могу придумать 4 варианта:
1) измените свою среду выполнения, чтобы обеспечить больший стек
2) Если у вас есть только один экземпляр struct Species, вы могли бы рассмотреть возможность объявления его глобально. Существует целая куча литературы о глобальных переменных и о том, когда, где, почему или почему-нет, так что вам следует изучить это, прежде чем решиться пойти по этому пути
3) выделять в куче, например

struct Species *s;
s = malloc(sizeof *s);

4) у вас есть переменная-член species.num Это, по-видимому, фактическое количество предметов, которые вы отслеживаете. Если это считывается откуда-то, например из базы данных или файла, то вы можете свести к минимуму использование памяти, выделяя большие массивы по отдельности, например
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, тогда нам не нужно идти и находить все места, которые мы выделяем() sp.x, и убеждаться, что тип согласен, который обрабатывается для нас компилятором.


DimaLevko

k5054, Спасибо большое. Вы ответили на мой вопрос. Теперь код работает. Спасибо.

[no name]

1

Рейтинг:
1

DimaLevko

Этот код выглядит следующим образом:

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


[no name]

1

Рейтинг:
0

KarstenK

Я бы пошел другим путем и определил структуру "только один вид", а не динамично создавал массив. Если у вас есть глобальные настройки, я бы использовал другую структуру для их хранения.

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