포트란에서 C++로 프로그램을 변환하고 있습니다.3 차원 배열 선언으로 인해 세그먼트 화 오류가 발생합니다.
float TC[100][100][100];
그리고 내가 그것을 실행하면 그때는 분할 오류 오류 :이 배열 선언을 추가 할 때까지
내 코드는 잘 실행 것으로 보인다. 이 배열은 8MB의 메모리를 차지하며 내 컴퓨터는 3GB를 차지합니다. 이 선언에 문제가 있습니까? 내 C++은 꽤 녹슬다.
포트란에서 C++로 프로그램을 변환하고 있습니다.3 차원 배열 선언으로 인해 세그먼트 화 오류가 발생합니다.
float TC[100][100][100];
그리고 내가 그것을 실행하면 그때는 분할 오류 오류 :이 배열 선언을 추가 할 때까지
내 코드는 잘 실행 것으로 보인다. 이 배열은 8MB의 메모리를 차지하며 내 컴퓨터는 3GB를 차지합니다. 이 선언에 문제가 있습니까? 내 C++은 꽤 녹슬다.
TC
이 자동 로컬 변수로 할당되고 있다고 생각합니다. 이것은 그것이 스택에 저장되고 있음을 의미합니다. 스택 메모리가 4MB가되지 않으므로 스택 오버플로가 발생합니다.
해결하려면 구조화 된 컨테이너 또는 new
과 함께 동적 할당을 사용하십시오.
도움 주셔서 감사합니다! 나는 Fortran에서 그런 것들을 다룰 필요가 없었기 때문에 그것에 대해 조금은 모릅니다. – user1042343
이것은 스택 기반 선언처럼 보입니다. 힙에서 할당 해 봅니다 (예 : new 연산자 사용).
함수 내부에서 로컬 변수로 선언하는 경우 스택에 크기가 커서 배열에 맞지 않을 수 있습니다. new
또는 malloc()
으로 힙에 할당하거나 디자인에서 허용하는 경우 전역 변수로 지정할 수 있습니다.
C++에서 스택에는 제한된 공간이 있습니다. MSVC는이 크기를 1MB로 기본 설정합니다. 스택이 1MB 이상을 사용하면 segfault 또는 stackoverflow 또는 무언가가 발생합니다. 이 구조체를 동적 메모리로 이동해야합니다. 동적 메모리로 이동하려면 이런 식으로 뭔가를 원하는 : 가변 배열, 그것은 액세스 할 때 처음으로 동적 메모리 구조를 할당합니다
typedef float (bigarray)[100][100][100];
bigarray& TC() {
static bigarray* ptr = NULL;
if (ptr == NULL) {
ptr = new float[100][100][100];
for(int j=0; j<100; j++) {
ptr[j] = new float[100][100];
for(int i=0; i<100; i++)
ptr[j][i] = new float[100];
}
}
return *ptr;
}
. 당신은 사각형 배열에서 더 많은 성능을 얻을 수 있지만, 당신은 유형을 변경해야합니다 :
typedef std::vector<std::array<std::array<float, 100>, 100> bigarray;
bigarray TC(100);
http://cs.nyu.edu/exact/core/doc/stackOverflow.txt에 따르면, GCC/리눅스 기본적으로 당신의 구조 충분히 크지 않다 8메가바이트에 스택의 크기,int main()
정말로 원한다면 MSVC에는 스택 크기를 32MB까지 늘릴 수있는 플래그가 있습니다. Linux에는 ulimit
명령이있어 최대 32MB의 스택 크기를 늘릴 수 있습니다.
고마워요! 이것은 꽤 도움이됩니다. – user1042343
그 배열은 약 4 메가 바이트입니다. 이 정의가 함수 내부에있는 경우 (로컬 변수로) 컴파일러는 스택에 저장하려고 시도합니다. 스택에서는 대부분의 시스템에서 그 정의를 커질 수 없습니다.
아마도 Fortran 컴파일러는 정적으로 할당했습니다 (포트란 루틴은 재귀 적으로 명시 적으로 표시되지 않으면 Fortran 루틴을 재귀 적으로 호출 할 수 없으므로 비 재귀 함수에 대해 정적 변수 할당이 작동하므로 오류가 발생하지 않습니다). 그곳에.
Fortran 함수가 재귀 적으로 선언되지 않았다고 가정하면 변수 static을 명시 적으로 선언하는 것이 좋습니다. 그러나 수정 된 버전에서 해당 함수를 재귀 적으로 호출하려고 시도하면 나중에이 문제가 발생할 수 있습니다. 그래서 더 나은 해결책은 아마 그것을 동적으로 할당하는 것입니다. 그러나 코드 시간이 길어 코드의 특성에 따라 성능이 너무 많이 손상 될 수 있습니다 (Fortran 코드는 성능 문제가있는 숫자 코드입니다).당신이 배열이 정적하도록 선택할 경우
, 당신은 실수로 재귀 호출에 대한 보호에 구축 할 수 있습니다 :
void yourfunction()
{
static bool active;
static float TC[100][100][100];
assert(!active);
active = true;
// your code
active = false;
}
분할 오류가 일반적으로 발생 당신이 허용되지 않는 메모리에 액세스하려고 할 때. 배열의 한계를 넘어선 적이 있습니까? – lvella
그 배열은 실제로 4MB보다 작은 공간을 필요로합니다. –