【问题标题】:Malloc call within a 2d array allocation function sometimes crashes二维数组分配函数中的 Malloc 调用有时会崩溃
【发布时间】:2013-07-29 07:12:24
【问题描述】:

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

我还开发了该函数的 realloc 和 dealloc 版本,但它们在代码中此时并未发挥作用。

我知道我应该开始使用调试器或内存检查工具,但我无法让它与 Eclipse Juno 一起使用。我可能会迁移到 Ubuntu 并尝试使用 valgrind,但如果可能的话,我希望现在避免使用它。

【问题讨论】:

  • 您检查过rowscolumns 的值是否合理?
  • @DrewMcGowen:是的,它们与我正在阅读的文件相匹配。
  • 听起来会发生这种情况,因为 'rows' 有一些奇怪的值。您能否在 malloc 之前验证该值是否正确?我还假设 t_rows、b_rows 等也是全局的。我在想它们上面的一些数组正在被覆盖并破坏它们。 (相当投机......我知道)。
  • 为什么t_fv需要**?看起来你正在做的事情有点矫枉过正。

标签: c arrays malloc 2d


【解决方案1】:

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

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

堆数据结构可能因缓冲区溢出/下溢而损坏。使用 valgrind 检测该或无效的array 指针条件。

【讨论】:

  • 感谢您的浏览。我将切换到 Ubuntu 并尝试 valgrind。
【解决方案2】:

我认为您在此处显示的代码中没有任何内容应该使其崩溃。我将您的程序放入 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 行和列以确保您没有请求不合理的大小。

我认为您的 //hidden 代码也可能有问题。

如果您启动并运行 Eclipse 或类似的东西,您会得到很好的服务。我认为使用这样的调试工具你会很快找到你的问题,因为你将能够找到你正在崩溃的确切行并找出你当时的内存状态。

【讨论】:

  • 请求的行和列太小,不可能是内存不足的问题。正如您所说,它可能与我的代码的其他部分有关。我从来没有在 c 中做过很多调试,但我想是时候开始了。非常感谢布赖恩看一看。至少你已经确认我的分配函数是正确的。
猜你喜欢
  • 2019-01-26
  • 1970-01-01
  • 2013-05-25
  • 1970-01-01
  • 2021-05-13
  • 2012-10-09
  • 2012-08-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多