Ошибка Seg, связанная со структурой и массивом вместе, но не по отдельности

#c #arrays #struct #segmentation-fault

#c #массивы #структура #ошибка сегментации

Вопрос:

Я пишу программу для своего исследования, которая требует нетривиальной схемы индексирования для работы с системой spin ice. Чтобы помочь с индексацией, я использую комбинацию структур и массивов. Каждая структура содержит 16 точек, содержащихся в кубической ячейке [я пытался опубликовать изображение кубической ячейки, но stackoverflow сказал, что для этого мне нужно как минимум 10 очков репутации, мои извинения], однако по числовым причинам позже их необходимо сохранить в одной матрице.

Значения, которые определяют размер системы (то есть, насколько велик куб моделирования), отлично работают для L = 1, L = 2, L = 3. Однако, когда я пытаюсь L = 4, у меня ошибка seg. Соответствующая часть кода выглядит следующим образом:

 /* The indexing of this program is as 
 *  (i,j,k) refers to which cubic cell you are in 
 *  (l,m) refers to which particle in the cubic cell you are in 
 *  the order is as follows
 *  (l,m) = (1,1) (1,3)   (3,1) (3,3)
 *          (1,0) (1,2)   (3,0) (3,2)
 * 
 *          (0,1) (0,3)   (2,1) (2,3)
 *          (0,0) (0,2)   (2,0) (2,2)
 */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define FOR_IJKLM for (i=0; i<L; i  ) 
                    for (j=0; j<L; j  ) 
                      for (k=0; k<L; k  ) 
                        for (l=0; l<4; l  ) 
                          for (m=0; m<4; m  )

// L  := integer length of convential cubic cell
// Np := Number of total particles in the system
#define L   4
#define Np  16*L*L*L

struct ConventialCube{
  double p[4][4][3];   // Position of particle 
  double mu[4][4][3];  // Magnetic Moment of particle
};

void initialize(struct ConventialCube cc[][L][L]);

int main(void){
  struct ConventialCube cc[L][L][L]; 
    initialize(cc); 

  double ewaldMatrix[Np][Np];

  return 0;
}

void initialize(struct ConventialCube cc[][L][L]){
  int i, j, k, l, m, d;
  double s = 1.0/sqrt(3);

  double sv[4][3] = {
    {-s,-s,-s},
    {-s, s, s},
    { s,-s, s},
    { s, s,-s}
  };
  double O[4][3] = {
    {0.0, 0.0, 0.0},
    {0.0, 0.5, 0.5},
    {0.5, 0.0, 0.5},
    {0.5, 0.5, 0.0}
  };

  FOR_IJKLM{
    double CO[] = {i,j,k};
    for (d=0; d<3; d  ){
      cc[i][j][k].mu[l][m][d] = sv[m][d];
      cc[i][j][k].p[l][m][d] = CO[d]   O[l][d]   O[m][d]/2.0;
    }
  }
}
  

Как упоминалось ранее, код выполняется для L = 1, L = 2, L = 3, однако при L = 4 он прерывается. Некоторые особенности, которые я обнаружил, заключаются в следующем:

  • закомментирование массива ewaldMatrix позволит запустить L = 4
  • изменение ewaldMatrix на целочисленный тип позволит запустить L = 4
  • закомментирование строки инициализации (cc) позволит запустить код
  • запись Np с меньшим количеством точек данных позволит ему работать (т. Е. определение Np как 16 * L LL-1)

Я был бы очень признателен за любой ввод или совет, поскольку случай L = 4 абсолютно необходим (на самом деле мне не нужно ничего выше L = 4, просто L = 4 — закон Мерфи, я думаю).

Комментарии:

1. Где происходит сбой?

2. Если вы разместите ссылку на свое изображение, я добавлю это в вопрос для вас.

3. Ну, что говорит ваш отладчик?

4. Я не уверен, что если я закомментирую матрицу и оставлю в ней структуру, она будет запущена. Если я закомментирую структуру и оставлю в ней матрицу, она будет запущена.

5. Переменная double ewaldMatrix[Np][Np]; в main слишком велика для локальной переменной, это приводит к переполнению стека здесь. В любом случае это не используется.

Ответ №1:

Вы переполняете стек. Объявите ваши два массива как статические:

 int main(void){
    static struct ConventialCube cc[L][L][L]; 
    initialize(cc); 

    static double ewaldMatrix[Np][Np];
    return 0;
}
  

или как глобальные:

 static struct ConventialCube cc[L][L][L]; 
static double ewaldMatrix[Np][Np];

int main(void){
    initialize(cc); 
    return 0;
}
  

Альтернативно, вы также могли бы объявить эти объекты в куче с помощью malloc() .