#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()
.