首页 文章

在2D阵列分配功能中的Malloc调用有时会崩溃

提问于
浏览
0

我正在使用指向1D数组的指针数组来模拟2d int数组 . 从文件中读取数据时,大小是动态的,因此我创建了动态分配函数( alloc2DArrInt ) . 它's been working well until I started testing my program with new data and now the first malloc sometimes crashes (segmentation fault?). Here'是代码的相关部分(我希望):

int** t_fv = NULL; // these are global
int** t_ofv = NULL;
int** b_fv = NULL;
int** b_ofv = NULL;

// assume these 2 lines are in main:

if (readFeatureVectors(&t_fv, &t_ofv, targetFilename, &trows, &tcolumns) < 0) { }
if (readFeatureVectors(&b_fv, &b_ofv, backgroundFilename, &brows, &bcolumns) < 0) { }

int readFeatureVectors(int*** fv, int*** ofv, char* fileName, int* rows, int* columns) {
    // hidden code
    alloc2DArrInt(fv, *rows, *columns); //&*fv
    alloc2DArrInt(ofv, *rows, *columns);
    // hidden code
}

void inline alloc2DArrInt(int*** array, int rows, int columns) {
    int i;
    *array = malloc(rows * sizeof(int*)); // sometimes crashes
    if (*array != NULL ) {
        for (i = 0; i < rows; i++) {
            (*array)[i] = malloc(columns * sizeof(int));
            if ((*array)[i] == NULL ) {
                printf("Error: alloc2DArrInt - %d columns for row %d\n", columns, i);
                exit(1);
            }
        }
    } else {
        printf("Error: alloc2DArrInt - rows\n");
        exit(1);
    }
}

t_fvt_ofvb_fv 的分配工作但程序在 b_ofv 的第一个malloc崩溃 . 当我切换 readFeatureVectors 调用的顺序时,程序在 t_fv (不是 t_ofv )的第一个malloc处崩溃 .

我还开发了函数的realloc和dealloc版本,但它们在代码中的这一点上还没有发挥作用 .

我知道我应该开始使用调试器或内存检查工具,但是我在使用Eclipse Juno时遇到了麻烦 . 我可能会迁移到Ubuntu并尝试使用valgrind,但我希望尽可能避免使用它 .

2 回答

  • 0

    malloc 行崩溃的唯一原因是堆数据结构是否已损坏,或者 array 指针是否无效 . 最有可能的结果是SIGSEGV .

    否则,无论您传递给它的任何参数,malloc都不会崩溃 . 它会在最坏的情况下返回NULL .

    例如,由于缓冲区溢出/下溢,堆数据结构可能被损坏 . 使用valgrind来检测那个或无效的 array 指针条件 .

  • 0

    我认为你的代码中没有任何东西可以让你崩溃 . 我把你的程序放到eclipse上并运行调试模式,它运行正常 . 我使用了以下代码:

    #define NULL 0
    
    int** t_fv = NULL; // these are global
    int** t_ofv = NULL;
    int** b_fv = NULL;
    int** b_ofv = NULL;
    
    int main()
    {
        int trows = 3000;
        int tcolumns = 3000;
    
        int brows = 5000;
        int bcolumns = 5000;
    
        char targetFilename[64] = "target";
        char backgroundFilename[64] = "background";
    
        if (readFeatureVectors(&t_fv, &t_ofv, targetFilename, &trows, &tcolumns) == 1)
        {printf("Worked1\n"); }
    
        if (readFeatureVectors(&b_fv, &b_ofv, backgroundFilename, &brows, &bcolumns) == 1)
        { printf("Worked2\n"); }
    
        printf("We are done now\n");
    
    }
    
    int readFeatureVectors(int*** fv, int*** ofv, char* fileName, int* rows, int* columns) {
        // hidden code
        alloc2DArrInt(fv, *rows, *columns); //&*fv
        alloc2DArrInt(ofv, *rows, *columns);
        // hidden code
    
        return 1;
    }
    
    void inline alloc2DArrInt(int*** array, int rows, int columns) {
        int i;
        *array = malloc(rows * sizeof(int*)); // sometimes crashes
        if (*array != NULL ) {
            for (i = 0; i < rows; i++) {
                (*array)[i] = malloc(columns * sizeof(int));
                if ((*array)[i] == NULL ) {
                    printf("Error: alloc2DArrInt - %d columns for row %d\n", columns, i);
                    exit(1);
                }
            }
        } else {
            printf("Error: alloc2DArrInt - rows\n");
            exit(1);
        }
    }
    

    一步一步走,它似乎一切正常 . 我尝试了3x3和5x5的小型阵列,它们也很好用 . 然后我尝试了10倍的大小,但我仍然没有内存耗尽 .

    我的第一个猜测是你要求的行和列的大小太大而你的内存不足 . 你可以在你的代码中等待一段忙碌的等待并进行内存检查以查看你的程序占用了多少(在linux中免费,在windows中的taskmgr) . 此外,您可以printf行和列,以确保您没有请求不合理的大小 .

    我认为您的隐藏代码也可能存在问题 .

    你可以很好地使Eclipse或类似的东西运行起来 . 我认为您可以使用类似的调试工具快速找到问题,因为您将能够找到正在崩溃的确切行并找出当时的内存状态 .

相关问题