2d数组分配函数内的malloc调用有时会崩溃

时间:2013-07-29 13:11:14

标签: c arrays malloc 2d

我正在使用指向1D数组的指针数组来模拟2d int数组。从文件中读取数据时,大小是动态的,因此我创建了动态分配函数( alloc2DArrInt )。它一直运行良好,直到我开始用新数据测试我的程序,现在第一个malloc有时会崩溃(分段错误?)。以下是代码的相关部分(我希望):

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_fv t_ofv b_fv 的分配有效,但程序在 b_ofv 。当我切换 readFeatureVectors 调用的顺序时,程序在 t_fv 的第一个malloc崩溃(不是 t_ofv )。

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

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

2 个答案:

答案 0 :(得分: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或类似的东西运行起来。我认为您可以使用类似的调试工具快速找到问题,因为您可以找到正在崩溃的确切行并找出当时的内存状态。

答案 1 :(得分:0)

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

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

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