Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <blockquote> <p>int* array = malloc(sizeof(int)<em>arraysize); int</em> temp = malloc(sizeof(int)*arraysize);</p> </blockquote> <p>In general, whenever you allocate memory, check that the allocation succeeded:</p> <pre><code>int *array = NULL, *temp = NULL; if (NULL == (array = malloc(sizeof(int)*arraysize))) { fprintf(stderr, "Out of memory allocating %d bytes\n", sizeof(int)*arraysize); abort(); } if (NULL == (temp = malloc(sizeof(int)*arraysize))) { fprintf(stderr, "Out of memory allocating %d bytes\n", sizeof(int)*arraysize); abort(); } </code></pre> <p>Then, a possibility would be to implement mergesorting <em>on disk</em>, using a file of integers (you can mmap() the file, too).</p> <p>But I find it strange that an allocation of 300000 integers on the heap - 4.8 megabytes at the most, using 64-bit integers - can cause an allocation error, so I think this is something in the mergesort implementation; maybe something having to do with a recursive implementation.</p> <p>I'd start with compiling the program with full debug information, and checking the core dump with <code>gdb</code>.</p> <h2>A "simple" malloc problem</h2> <p>Having to handle a very large array of <em>ASCII strings representing numbers</em>, you could start by first converting it to a file of <em>integers</em>.</p> <pre><code>FILE *fi, *fo, *ft; char buffer[20]; int array[4096], b = 0; fi = fopen("DATASET.dat", "r"); if (NULL == fi) { fprintf(stderr, "Cannot open input file\n"); abort(); } fo = fopen("INTEGER.dat", "w"); if (NULL == fo) { fprintf(stderr, "Cannot open output file\n"); abort(); } ft = fopen("TEMP.dat", "w"); if (NULL == ft) { fprintf(stderr, "Cannot open output file\n"); abort(); } for(i=0; i&lt;arraysize; i++){ fgets(buffer, 20, fi); array[b++] = atoi(buffer); if (4096 == b) { if (b != fwrite(buffer, sizeof(int), b, fo)) { fprintf(stderr, "write error\n"); abort(); } if (b != fwrite(buffer, sizeof(int), b, ft)) { fprintf(stderr, "write error\n"); abort(); } b = 0; } } if (b) { if (b != fwrite(buffer, sizeof(int), b, fo)) { fprintf(stderr, "write error\n"); abort(); } if (b != fwrite(buffer, sizeof(int), b, ft)) { fprintf(stderr, "write error\n"); abort(); } } fclose(fi); fi = NULL; fclose(fo); fo = NULL; fclose(ft); ft = NULL; </code></pre> <p>Now you have an <code>INTEGER.dat</code> file which is made of integers of fixed size. It is, to all intents and purposes, a file copy of an array in memory. Same goes for the temporary array.</p> <p>And you <em>can</em> tell the system to treat that file as if it was an array in memory.</p> <pre><code>int *sort = NULL; int *temp = NULL; // Temp is not shown -- identical treatment as sort fd = open ("INTEGERS.dat", O_RDWR); if (fd == -1) { fprintf(stderr, "cannot reopen output\n"); abort(); } if (MAP_FAILED == (sort = mmap (0, arraysize*sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0))) { fprintf(stderr, "mmap error\n"); abort(); } if (-1 == close (fd)) { fprintf(stderr, "error closing output file\n"); return 1; } do_sort(sort, temp, arraysize); if (-1 == munmap (sort, arraysize*sizeof(int))) { fprintf(stderr, "error releasing mmap for %s\n", "sort"); abort(); } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload