递归函数中的Malloc崩溃



我目前正在编码Burrows-Wheeler变换的实现,它需要对(大)数组进行排序。由于我想并行化递归排序函数的部分代码,所以我决定在堆中分配一些局部变量(使用malloc()),以防止堆栈溢出,或者至少使程序优雅地停止运行。这引发了一大堆新的问题。我将代码剥离到最重要的部分(即,是什么导致了问题)。

下面的代码编译没有错误。当使用icc编译时,生成的程序可以正常工作,但当使用gcc或tcc编译时,它会崩溃(随机)。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
unsigned char *block;
int *indexes, *indexes_copy;
void radixsort(int from, int to, int step)
{
    int *occurrences, *first_index_of, i;
    if((occurrences = malloc(1024)) == 0)
        exit(1);
    if((first_index_of = malloc(1024)) == 0)
        exit(1);
    memset(occurrences, 0, 1024);
    for(i = from; i < to; i++)
        occurrences[block[indexes[i] + step]]++;
    first_index_of[0] = from;
    for(i = 0; i < 256; i++)
        first_index_of[i + 1] = first_index_of[i] + occurrences[i];
    memset(occurrences, 0, 1024);
    memcpy(&indexes_copy[from], &indexes[from], 4 * (to - from));
    for(i = from; i < to; i++)
        indexes[first_index_of[block[indexes_copy[i] + step]] + occurrences[block[indexes_copy[i] + step]]++] = indexes_copy[i];
    for(i = 0; i < 256; i++)
    if(occurrences[i] > 1)
        radixsort(first_index_of[i], first_index_of[i] + occurrences[i], step + 1);
    free(occurrences);
    free(first_index_of);
}
int main(int argument_count, char *arguments[])
{
    int block_length, i;
    FILE *input_file = fopen(arguments[1], "rb");
    fseek(input_file, 0, SEEK_END);
    block_length = ftell(input_file);
    rewind(input_file);
    block = malloc(block_length);
    indexes = malloc(4 * block_length);
    indexes_copy = malloc(4 * block_length);
    fread(block, 1, block_length, input_file);
    for(i = 0; i < block_length; i++)
        indexes[i] = i;
    radixsort(0, block_length, 0);
    exit(0);
}

即使输入是一个非常小的文本文件(大约50字节),该程序在后两个编译器中也非常不稳定。它以50%的概率工作。在其他情况下,当调用malloc()时,它会在radixsort的第二次或第三次迭代中崩溃。当输入文件较大(大约1 MiB)时,总是崩溃。同样在第二次或第三次迭代中…

手动增加堆没有任何好处。不管怎样,它都不应该。如果malloc()不能分配内存,它应该返回一个NULL指针(而不是崩溃)。

从堆切换回堆栈使程序可以在任何一个编译器下工作(只要输入文件足够小)。

那么,我错过了什么/做错了什么?

if((occurrences = malloc(1024)) == 0)
make that:
if((occurrences = malloc(1024 * sizeof *occurences)) == 0)

但是还有更多的问题…

UPDATE(1024 = 4 * 256似乎只是风格…)

for(i = 0; i < 256; i++)
    first_index_of[i + 1] = first_index_of[i] + occurrences[i];

相关内容

  • 没有找到相关文章

最新更新