涉及malloc的C代码,用于在编译后动态分配2D数组崩溃

时间:2017-08-01 19:52:31

标签: c arrays malloc dynamic-arrays

我正在尝试将数组的行维(a)分配给用户输入值的大小。这是我的代码:

#include <stdio.h>
#include <stdlib.h>

void FreeArray(int **arry, int N);

int main() {
    int **a;
    int **b;
    int N_a;
    int N;
    if (a != NULL) {
        FreeArray(a, N);
    }
    if (b != NULL) {
        FreeArray(b, N);
    }
    do {
        printf("Enter the size of the NxN array:\n");
        scanf("%d", &N);
        if (N < 2) {
            printf("Error, enter correct size.\n");
        }
    } while (N < 2);
    N_a = N;
    int errorInAlloc = 0;
    a = (int**)malloc(N_a * sizeof(int*));
    if (a != NULL) {
        errorInAlloc = 1;
    }
    return 0;
}

void FreeArray(int **arr, int N) {
    int i;
    if (arr == NULL)
        return;
    if (arr != NULL) {
        for (i = 0; i < N; i++) {
            if (arr[i] != NULL)
                free(arr[i]);
        }
        free(arr);
    }
}

我们提供了FreeArray功能,所以我知道它是正确的。这里还有其他代码,但我省略了,因为它只是一个菜单。当我注释掉a = (int**) malloc(N_a * sizeof(int*));时,程序会编译并运行而不会崩溃或出现问题。当我包含这一行时,程序会编译,但当我输入一个大于或等于2的数字时,它会崩溃。我也尝试了a = malloc(N_a * sizeof(int*));a = (int**)malloc(N * sizeof(int*));以及a = malloc(N * sizeof(int*));,但所有人都做了同样的事情。

我一直在Code :: Blocks中编写和运行程序,但即使我通过命令提示符编译它,它仍然会崩溃。

在一个美好的一天,我很难使用数组,所以动态分配数组对我来说太混乱了,非常感谢任何帮助!

3 个答案:

答案 0 :(得分:2)

您的计划中有多处错误:

  • 变量ab未初始化,将它们与NULL进行比较毫无意义,并将它们传递给FreeArray具有未定义的行为。

  • 考虑如何编写FreeArray函数,必须分两步执行分配:

    • 分配一组指针,你可以这样做。
    • 使用已分配的int数组的地址初始化数组的每个元素。你没有。

以下是函数AllocArray的编写方式:

int **AllocArray(int N) {
    int i;
    int **arr = calloc(sizeof(*arr), N);
    if (arr != NULL) {
        for (i = 0; i < N; i++) {
            arr[i] = calloc(sizeof(*arr[i]), N);
            if (arr[i] == NULL) {
                /* allocation failed: free allocated portion and return NULL */
                while (i-- > 0) {
                    free(arr[i]);
                }
                free(arr);
                return NULL;
            }
        }
    }
    return arr;
}

请注意,FreeArray功能可以通过以下方式简化:

void FreeArray(int **arr, int N) {
    int i;
    if (arr != NULL) {
        for (i = 0; i < N; i++) {
            free(arr[i]);
        }
        free(arr);
    }
}

可以将空指针传递给free(),而arr上的单个测试就足够了。

答案 1 :(得分:1)

第一个问题是你释放了一个未分配的指针:

 if(a != NULL)
 {
     FreeArray(a, N);
 }

您从未为a分配内存,因此当您尝试访问向量的位置时,会生成分段错误(与b相同)。如果您想确保指针为NULL,请使用a = NULL;。这将解决您的问题。

还有另一个逻辑问题:

if(a != NULL)
{
    errorInAlloc = 1;
}

如果a与NULL不同,则返回分配错误。如果a NULL,则应返回错误,这意味着内存分配中发生错误。

答案 2 :(得分:0)

这是gcc在编写代码时报告的更多警告。

gcc -o xx xx.c -Wall -Wextra -pedantic -std=c99 -O2 -Wmissing-declarations -Wmissing-prototypes -Wconversion
xx.c: In function ‘main’:
xx.c:26:26: warning: conversion to ‘long unsigned int’ from ‘int’ may change the sign of the result [-Wsign-conversion]
a = (int **) malloc(N_a * sizeof(int *));
                      ^
xx.c:25:6: warning: variable ‘errorInAlloc’ set but not used [-Wunused-but-set-variable]
int errorInAlloc = 0;
  ^
xx.c:10:5: warning: ‘a’ is used uninitialized in this function [-Wuninitialized]
if (a != NULL) {
 ^
xx.c:13:5: warning: ‘b’ is used uninitialized in this function [-Wuninitialized]
if (b != NULL) {
 ^
xx.c:11:3: warning: ‘N’ may be used uninitialized in this function [-Wmaybe-uninitialized]
FreeArray(a, N);
^

格式化有点偏。重点非常明确:让编译器帮助您找到错误。