함수의 argument로 큰 array를 넣으면 오류가 날 수도 있나요?
Segmnetation Fault (core dumped)의 문제입니다
저는 컴퓨터 관련 업종에 종사하고 있지 않고 단순히 계산을 위해서 C를 사용하려고 생각했습니다
다른 Mathematical tool로 하기에는 계산의 양이 너무 방대하거든요
제 프로그램은 이렇습니다
U는 7차원의 array입니다 4차원 좌표에,방향이 주어지면 거기에 있는 3x3 행렬 하나가 있죠
(x,y,z,w좌표,방향, 행렬인덱스 i,j라서 7차원)
어떤 function, Wall(U) 에 넣으면 U에 대한 정보를 바탕으로 4차원 좌표와 방향을 바꾸어 탐색하면서 행렬들을 가지고 계산을 합니다
그런데 U는 행렬의 분포인데 저는 시간에 따라 행렬의 분포를 바꾸어가면서 계산을 하고 싶어서 8차원 행렬 V를 선언했습니다
for(m) for (...) V[m][...]=U[...]; 과 같은 방법으로 대입해가면서 각각 다른 분포를 전부 V에다 집어넣었죠
그 다음엔 함수 Wall로 측정을 하고 싶어서
for(m) A[m]=W(V[m]); 와 같은 방법으로 값을 얻고자 했는데, 이 단계에서 Segmentation Fault Error가 뜨더군요
제가 생각하기엔 U 하나와 V[m] 하나는 동등하니까 에러가 날 이유가 없는 것 같더라구요
그리고 이미 더 낮은 차원에서 이런 방법이 되는 것도 확인했구요 (이를테면 double B[3][3]을 아규먼트로 하는 함수는 double C[4][3][3]의 C[1]을 B대신 아규먼트로 받아서 잘 계산하더라구요)
그러면 제가 생각하는 이유는 행렬의 사이즈가 커서 받아줄 수가 없나 걱정이 되더라구요 그러면 아예 프로그램을 다시 짜야 할테니까
제 질문은
1. 큰 행렬 내지는 메모리를 많이 차지하는 변수를 아규먼트로 함수에 전달했을 때 segmentation Fault가 일어날 수 있는지
2. 혹 그렇다면 변수의 사이즈를 줄이면서 합리적으로 행렬의 분포를 구현할 만한 방법이 있는지 등입니다
--------------------------------------------------------------------------------------------------------------
죄송합니다 실수가 있었네요 7차원으로든 8차원으로든 function에 돌리면 안 돌아가네요
main함수에 function W()내용을 그대로 복사해와서 돌리면 7차원 행렬은 되고 8차원은 안 됩니다
제 질문은 여전히 동일한데 똑같은 계산인데 함수로 만들어 돌리면 안 되는 이유는 무엇인지가 궁금합니다
정확한 답변은 아닐 수 있겠지만, 일단 제가 아는 선에서 답변을 하나 남겨볼께요.
안녕하세요.
일단 기본적으로 배열의 사이즈가 기본 프로그램에 할당한 Heap의 용량이 넘어가지 않는 한, 사이즈에 따른 오류가 나지는 않으실 꺼 같습니다.
제가 7차원, 8차원 배열까지는 만져본적은 없지만 기본적으로 2차원배열이나 3차원배열 넘길때도, 문제가 생기는 부분입니다.
배열이란게, 결국 C의 Pointer와 관련된 부분이라 전공자가 아니시라니... 이부분이 복잡하다면 복잡할 수도 있는 부분이라 설명은 배제하구요.
그냥 쉽게 말씀드리면, 구지 생업이 아니신데 복잡한 개념을 숙지하기 보단 Global 변수로 선언해서 사용하시는게 단순계산결과값만 필요하신 경우라면 더 이득이 될 듯 싶습니다.
아마, C를 생업으로 하시는분들이라면 더 좋은 답을 주실 수도 있구요.
또 질문의 요지가 많이 큰값을 넘길 시 오류가 날 수 있는 부분인가요? 라는 의미에 대해서는 앞에서 설명하였듯, 컴파일 시 최대 Heap사이즈를 넘어가면 오류가 날 수 있지만,
현재 처한 사항은 그런 케이스가 아니라 다른답변을 드렸습니다.
main 함수 내에서 모두 구현했을 때는 잘 돌아가시는데, 함수로 구조화 했을 때 돌아가지 않는 부분이라 이는 Caller 와 Callee 간에 메모리 전달과정에서 나는 오류라 생각되기때문에
앞과 같은 답변을 드립니다.
허접한 답변 읽어주셔서 감사합니다.
정말 감사합니다 덕분에 메모리 할당과 사이즈를
정말 감사합니다
덕분에 메모리 할당과 사이즈를 체크해봤습니다
제 배열은 로컬 변수 선언이라 힙이 아니라 스택으로 가고 제 시스템의 스택 사이즈는 고작 8192KB였네요
로컬 변수 다 합쳐서 8192 KB 안되게 맞추니까 돌아는 갑니다
함수로 쓸 수 없었던 것도 아규먼트로 받는 변수를 복사해서 스택으로 보내니까 스택 사이즈를 초과해서 그런가 봅니다
메모리를 변수에 동적할당하면 힙을 사용할 수 있고 힙은 사이즈에 제한이 없다니까 좀 더 잘 돌아갈 것 같은데,
complex.h에 있는 complex double을 사용하니 동적할당된 변수들이 배열로 인식이 잘 안되네요
double 동적할당은 아무런 문제 없는데...
덕분에 필요한 부분 체크하고 답을 얻었습니다
정말 감사합니다
동일한 문제를 발생시키는, 예제 코드를 만들어서
동일한 문제를 발생시키는, 예제 코드를 만들어서 올려주세요. 어차피 배열 복사라 만드기는 어렵지 않을 겁니다.
그걸 만드는 사이에 문제를 발견하실 수도 있고, 도움 받기도 쉬울 겁니다.
stack 영역의 크기는 제한되어
stack 영역의 크기는 제한되어 있습니다.
혹시 stack 영역에 선언하셨으면 stack 대신에
heap 영역에 한번 메모리 요청해보시겠어요?(malloc())
heap 도 마찬가지로 연속적으로 할당 받을 수 있는 건 한계가 있지만,
stack 영역에 비해 매우 큽니다.
감사합니다 저도 아까 십분 전에 스택과 힙에 관한
감사합니다 저도 아까 십분 전에 스택과 힙에 관한 내용을 읽고 아 로컬변수로 선언되어서 그렇구나 했습니다
제 스택사이즈는 ulimit -s 명령어로 보니 8192KB였습니다
저도 동적할당으로 하는 게 더 나을 것 같긴 합니다
다만, 복소수를 쓰기 위해서 complex.h에 있는 complex double을 여러 차원으로 동적할당하니 배열로 인식이 잘 안됩니다
컴파일러에서 자꾸 워닝을 주는데 무시하고 해봤더니 그 경우에도 segmentation fault가 나더군요
이 경우는 다른 이유로 segmentation fault가 나는 것 같긴 한데 다른 라이브러리를 구해야하나 하고 고민하고 있습니다
친절한 답변 감사합니다
생성자들이 제대로 불리는지...
complex double에 생성자가 어떤 종류가 있는지 확인해보시구 원하는 배열 크기만큼 호출 되는지 체크해 보세요~
댓글 달기