[해결]c언어로 sorting하는 프로그램에서 2^20개의 데이터를 정렬하려고 하면 segmentation fault가 일어납니다.

interoasis의 이미지

  sorting.h  
  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <time.h>
  4
  5 #define RANGE 2001
  6
  7 void swap(double *first, double *second)
  8 {
  9         double temp;
 10
 11         temp = *first;
 12         *first = *second;
 13         *second = temp;
 14 }
 15
 16 void copyarray(double original[], double temp[], int size)
 17 {
 18         int i;
 19
 20         for(i = 0; i < size; i++)
 21                 temp[i] = original[i];
 22 }
 23
 24 void exchangesort(int size, double data[])
 25 {
 26         int i, j;
 27
 28         for(i = 0; i < size; i++)
 29                 for(j = i + 1; j < size; j++)
 30                         if(data[j] < data[i])
 31                                 swap(&data[i], &data[j]);
 32 }
 
 main.c
 
  1 #include "sorting.h"
  2
  3 int main(void)
  4 {
  5         double data1[16], data2[32], data3[64], data4[128], data5[256], data6[512],
  6         data7[1024], data8[2048], data9[4096], data10[8192], data11[16384],
  7         data12[32768], data13[65536], data14[131072], data15[262144], data16[524288]; //data17[1048576];
  8         double temp1[16], temp2[32], temp3[64], temp4[128], temp5[256], temp6[512],
  9         temp7[1024], temp8[2048], temp9[4096], temp10[8192], temp11[16384],
 10         temp12[32768], temp13[65536], temp14[131072], temp15[262144], temp16[524288]; //temp17[1048576];
 11         int i;
 12         clock_t start;
 13         double end;
 14         srand(time(NULL));
 15
 16         for(i = 0; i < 16; i++)
 17                 data1[i] = (double)(rand() % RANGE - 1000) / 10.0;
 18         for(i = 0; i < 32; i++)
 19                 data2[i] = (double)(rand() % RANGE - 1000) / 10.0;
 
                               중략
 
 44         for(i = 0; i < 262144; i++)
 45                 data15[i] = (double)(rand() % RANGE - 1000) / 10.0;
 46         for(i = 0; i < 524288; i++)
 47                 data16[i] = (double)(rand() % RANGE - 1000) / 10.0;
 48         /*for(i = 0; i < 1048576; i++)
 49                 data17[i] = (double)(rand() % RANGE - 1000) / 10.0;*/
 50
 51         copyarray(data1, temp1, 16);
 52         copyarray(data2, temp2, 32);
 53         copyarray(data3, temp3, 64);
 54         copyarray(data4, temp4, 128);
 55         copyarray(data5, temp5, 256);
 56         copyarray(data6, temp6, 512);
 
                   중략
 
 65         copyarray(data15, temp15, 262144);
 66         copyarray(data16, temp16, 524288);
 67         //copyarray(data17, temp17, 1048576);
 68
 69         start = clock();
 70         exchangesort(16, temp1);
 71         end = (double)(clock() - start) / CLOCKS_PER_SEC;
 72         printf("\nExchange Sort 변수개수 : 2^4   %f\n", end);
 73         start = clock();
 74         exchangesort(32, temp2);
 75         end = (double)(clock() - start) / CLOCKS_PER_SEC;
 76         printf("\nExchange Sort 변수개수 : 2^5   %f\n", end);
 77         start = clock();
 78         exchangesort(64, temp3);
 79         end = (double)(clock() - start) / CLOCKS_PER_SEC;
 80         printf("\nExchange Sort 변수개수 : 2^6   %f\n", end);
 
 
                            중략
 
129         start = clock();
130         exchangesort(524288, temp16);
131         end = (double)(clock() - start) / CLOCKS_PER_SEC;
132         printf("\nExchange Sort 변수개수 : 2^19  %f\n", end);
133         /*start = clock();
134         exchangesort(1048576, temp17);
135         end = (double)(clock() - start) / CLOCKS_PER_SEC;
136         printf("\nExchange Sort 변수개수 : 2^20  %f\n", end);*/
 
 
                             중략
 
312         return 0;
313}

위처럼 2^4부터 2^20까지의 데이터를 각각 정렬하면서 걸린 시간을 측정하려고 하는데요. 이상하게 2^19까지는 정상적으로 프로그램이 실행되는데 2^20까지 포함시키면 segmentation fault가 발생합니다. gdb로 보니까 srand(time(NULL))쪽을 지적하던데 랜덤시드함수도 세그멘터이션 폴트의 원인이 될 수 있나요?

더 문제는 위의 방법으로 Merge Sort와 Quick Sort로도 시간측정을 해서 비교해야 하는데 그때는 2^19마저도 segmentation fault가 일어난다는 것입니다. C언어 초보에게 조언좀 부탁드리겠습니다.

shint의 이미지

unsigned double 이나 double double 이런거면 안될까요?? ㅇ_ㅇ?

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

interoasis의 이미지

주어진 문제의 조건이 input data가 소수점 첫째자리까지 나타내고 랜덤숫자의 범위가 -100.0 ~ 100.0이거든요.
unsigned double이나 double double이라는게 있다는걸 처음 알았네요. -_-a C언어에도 있는건가요?

근데 이 세그먼트 폴트가 나타낼 수 있는 한도를 초과해버려서 나타나는 문제인가요?
2^20이래봤자 100만개가 조금 넘는수준의 데이터인데 거기에 8바이트를 곱해봐도 기껏해야 8메가 정도...
그리고 100만개가 넘는 데이터를 숫자로 표시하는건 배열 인덱스정도밖에 없으니 int정도면 충분히 다 표현할 수 있을것 같은데 말이죠.

정작 double타입의 데이터는 -100.0에서 100.0을 넘지 않게 설정돼있어서 double이 아까울 정도입니다.;;

익명 사용자의 이미지

Hey, try 64bit programming.

interoasis의 이미지

Is this 32bit programming's limit??;;

ifree의 이미지

double 이 2^20 이면 데이타가 2^28 바이트이고 다른 데이타도 있으니 메모리가 모자랄 수 있겠네요.
윈도우즈에서 32비트 프로그램에 할당되는 메모리는 코드 포함 최대 2기가입니다.

익명 사용자의 이미지

32비트에서는 최대 4기가입니당

DarkSide의 이미지

전체 시스템에서 최대 4기가이고, 개별 프로그램에서는 2기가가 맞아요.

interoasis의 이미지

제가 뭔가를 착각하고 있는것 같은데...

제 생각으로는 double 데이타 타입은 8바이트이고 데이터의 개수가 2^20만 따져봤을때 대충 100만개로 치자면
1,000,000 X 8바이트 = 8,000,000바이트가 되는것 아닌가요? 그럼 8메가정도의 용량을 차지하는걸로 생각되는데,,
이것대로라면 다른 데이터를 다 합쳐도 메모리 모자랄 상황은 벌어지지 않을것 같아서요.

제 생각이 어디서 잘못된건가요?;;

kaeri17의 이미지

잘 계산 하셨습니다. 그리고 16바이트인것 부터 한꺼번에 계산하니까 물리적인 메모리 사용량은 16메가정도 되겠네요. 문제는 스택 사이즈입니다. 스택은 이변수들을 다 가질만큼 크지 못하죠. 밑에 해결책을 써 놨는데 잘못 생각하실까봐 댓글을 답니다.

interoasis의 이미지

감사합니다.:)

kaeri17의 이미지

heap에다가 생성을 해 보시는 것도 나쁘지 않을 방법 같고요. 아마 스택 사이즈를 오버하는것 같은데 뭔가 컴파일할때 관련된 옵션을 줘서 해결할수 있던것 같기도 하고요. 정확히 기억은 안납니다. 아마 malloc을 사용해서 힙에다가 생성하면 확실히 될듯 합니다.

kaeri17의 이미지

http://powerson.egloos.com/1555146 이걸 보시면 될듯 합니다.

interoasis의 이미지

아~ 개인유저별 스택사이즈 제한이란것도 있었군요. 이게 원인이 맞는것 같습니다.
한번 이대로 시도해봐야겠네요. 답변 감사드립니다.

p.s : 해결됐습니다. 감사합니다.

DarkSide의 이미지

데이타가 딱 봐도 100 메가 넘을 것 같은데, 당연히 스택은 안되죠.
컴파일 옵션을 쓰세요,

interoasis의 이미지

스택사이즈를 50메가 정도로 잡으니까 정상적으로 해결됩니다만

컴파일부분의 어떤 옵션을 쓰면 또 이 문제를 해결할 수 있는건가요?
되도록이면 여러가지 해결방법을 알아두고 싶네요.
스택이 아닌 다른 자료구조로도 프로그램 실행이 될 수 있나요?

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.