首页 文章

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

提问于
浏览
0

我试图将数组的行维度( 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

    您的程序中有多个错误:

    • 变量 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 上的单个测试就足够了 .

  • 2

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

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

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

    还有另一个逻辑问题:

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

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

  • 1

    这是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);
    ^
    

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

相关问题