C分配2维整数数组

时间:2015-04-29 00:49:29

标签: c arrays malloc realloc

如何使用table()#Source: local data frame [2 x 3] # # A B C #1 0 4700 5400 #2 1 9400 10800 声明全局变量二维整数数组realloc然后重新分配一次malloc和{{1}的数字给出的是int array[][]

3 个答案:

答案 0 :(得分:0)

在C中模拟2D数组或矩阵时,需要考虑几点。首先要了解实际分配的内容。要模拟您只能通过array[m][n]访问的2D数组,您要做的是首先为指向int 的指针分配m 指针数组。这提供了m int*(或行),您可以分配n int (列)。

简单地说,您可以分配m pointers to int* n int

现在,在我们查看代码之前,可以选择使用malloc来分配内存(具体是列)还是使用calloc。为什么?在您甚至尝试访问数组元素之前,必须初始化该元素以保存某个值。否则,任何尝试从该元素读取的尝试都是尝试从未初始化的值中读取未定义的行为,并且可以将您的程序发送到不归路的地方..

为什么calloc代替malloccalloc不仅为您分配空间,还会将该位置的内存初始化/设置为0/NULL0,如果是数字类型,NULL指针的情况 - 两者都是有效的0)这可以防止无意识读取未初始化的元素,因为所有元素都被初始化为0开始。现在你可以自由地设置一个循环并将每个值设置为0(或者其他),但是新的C程序员经常会忽略它。因此calloc可以帮助保护您免受自己的伤害。我们来看一下分配函数:

/* allocate/initialize mxn matrix */
int **mtrx_calloc (size_t m, size_t n)
{
    register size_t i;
    int **array = calloc (m, sizeof *array);

    if (!array) {   /* validate allocation  */
        fprintf (stderr, "%s() error: memory allocation failed.\n", __func__);
        exit (EXIT_FAILURE);
    }

    for (i = 0; i < m; i++)
    {
        array[i] = calloc (n, sizeof **array);

        if (!array[i]) {   /* validate allocation  */
            fprintf (stderr, "%s() error: memory allocation failed.\n", __func__);
            exit (EXIT_FAILURE);
        }
    }
    return array;
}

分配功能很简单。它接受mn作为参数(类型 size_t - 索引不能为负),并返回一个完全分配的,完全初始化的{{1指向m n数组的指针。让我们看看它用于将int分配为my_array的{​​{1}}矩阵:

4x5

在整个代码的其余部分中,您可以通过int访问任何元素(索引基于零,就像C中的其余索引一样)

int **my_array = mtrx_calloc (4, 5); 怎么样?当您谈论固定大小的数组时,您需要重新分配内存的唯一时间是您需要调整数组的大小。 (现在授予你可以创建一个新数组并复制旧/新)但是,由于重新分配内存是C中的一个重要概念,让我们编写一个函数来重新分配矩阵的行数。

假设您现在发现需要my_array[0-3][0-4]作为realloc矩阵而不是my_array矩阵。在这种情况下,您需要8x5 4x5的数量才能添加realloc行。您还需要分配空间来保存行pointers to int*的新值(索引4)。

您还需要跟踪已分配的行数,因此如果我们发送指向当前行数的指针,我们可以更新该地址的值并在我们的调用函数中返回值(在这种情况下为5-8)。在我们调用重新分配之前,我们需要在4-7中保留的唯一内容是main()的旧值(允许用值填充新空间等)。我们的行重新分配可能看起来如此如下:

main

现在重要的是要注意,我们不会直接将新重新分配的值分配给我们的数组变量,而是直接分配给m变量。为什么?如果重新分配失败,/* realloc an array of pointers to int* setting memory to 0. */ int **realloc_rows (int **ap, size_t *m, size_t n, size_t newm) { if (newm <= *m) return ap; size_t i = 0; int **tmp = realloc (ap, newm * sizeof *ap); if (!tmp) { fprintf (stderr, "%s() error: memory reallocation failure.\n", __func__); // return NULL; exit (EXIT_FAILURE); } ap = tmp; for (i = *m; i < newm; i++) { ap[i] = calloc (n, sizeof **ap); if (!ap[i]) { /* validate allocation */ fprintf (stderr, "%s() error: memory allocation failed.\n", __func__); exit (EXIT_FAILURE); } } *m = newm; return ap; } 将释放新分配的空格返回tmp,如果我们已将realloc的返回值分配给数组,则会导致数据完全丢失。通过使用NULL数组,您可以根据需要灵活地处理故障。重新分配4个额外行的示例调用如下所示:

realloc

这比我最初预期的2D矩阵/阵列的概述要长得多,但是即使是一组简单的函数也需要考虑动态分配和重新分配模拟的2D阵列。有了这个,我们将给你一个例子来看看。该示例默认情况下将创建一个3x4 2D数组,但您也可以将该大小指定为程序的参数。例如:

tmp

将创建一个初始的4x5 2D阵列,而不是默认值。要显示realloc的使用,最初分配的任何大小都将调整大小以添加4行并使用其他值填充新行。原始大小和重新分配的大小数组都打印到my_array = realloc_rows (my_array, &m, n, m + 4); 。如果您有疑问,请告诉我们:

./programname 4 5

创建4x5矩阵并重新分配到8x5

stdout

检查内存错误/泄漏

/*
    gcc -Wall -Wextra -o progname progname.c
*/

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

int **mtrx_calloc (size_t m, size_t n);                /* initialize elements to 0  */
int **realloc_rows (int **ap, size_t *m, size_t n, size_t newm); /* resize newm x n */
void mtrx_prn (size_t m, size_t n, int **matrix);      /* print matrix with/pad     */
void mtrx_free (size_t m, int **matrix);               /* free memory allocated     */

int main (int argc, char **argv)
{
    /* set initial size from arguments given (default: 3 x 4) */
    size_t m = argc > 2 ? (size_t)atoi (argv[1]) : 3;
    size_t n = argc > 2 ? (size_t)atoi (argv[2]) : 4;

    /* allocate the m x n matrix */
    int **matrix = mtrx_calloc (m, n);

    /* fill with misc values */
    register size_t i = 0, j = 0;
    for (i = 0; i < m; i++)
    {
        for (j = 0; j < n; j++)
            matrix [i][j] = (int)(i + j);
    }

    /* print matrix */
    printf ("\nThe dynamically allocated %zux%zu matrix is:\n\n", m, n);
    mtrx_prn (m, n, matrix);

    /* reallocate matrix - add 4 rows */
    printf ("\nReallocate matrix to %zux%zu:\n\n", m + 4, n);
    size_t oldm = m;
    matrix = realloc_rows (matrix, &m, n, m + 4);

    /* fill new rows with misc values */
    for (i = oldm; i < m; i++)
    {
        for (j = 0; j < n; j++)
            matrix [i][j] = (int)(i + j);
    }

    mtrx_prn (m, n, matrix);

    /* free memory alocated */
    mtrx_free (m, matrix);

    /* just to make it look pretty */
    printf ("\n");

    return 0;
}

/* allocate/initialize mxn matrix */
int **mtrx_calloc (size_t m, size_t n)
{
    register size_t i;
    int **array = calloc (m, sizeof *array);

    if (!array) {   /* validate allocation  */
        fprintf (stderr, "%s() error: memory allocation failed.\n", __func__);
        exit (EXIT_FAILURE);
    }

    for (i = 0; i < m; i++)
    {
        array[i] = calloc (n, sizeof **array);

        if (!array[i]) {   /* validate allocation  */
            fprintf (stderr, "%s() error: memory allocation failed.\n", __func__);
            exit (EXIT_FAILURE);
        }
    }
    return array;
}

/* realloc an array of pointers to int* setting memory to 0. */
int **realloc_rows (int **ap, size_t *m, size_t n, size_t newm)
{
    if (newm <= *m) return ap;
    size_t i = 0;
    int **tmp = realloc (ap, newm * sizeof *ap);
    if (!tmp) {
        fprintf (stderr, "%s() error: memory reallocation failure.\n", __func__);
        // return NULL;
        exit (EXIT_FAILURE);
    }
    ap = tmp;

    for (i = *m; i < newm; i++)
    {
        ap[i] = calloc (n, sizeof **ap);

        if (!ap[i]) {   /* validate allocation  */
            fprintf (stderr, "%s() error: memory allocation failed.\n", __func__);
            exit (EXIT_FAILURE);
        }
    }
    *m = newm;

    return ap;
}

/* print a (m x n) matrix (check pad alloc) */
void mtrx_prn (size_t m, size_t n, int **matrix)
{
    register size_t i, j;

    for (i = 0; i < m; i++)
    {
        char *format = "[ %2d";
        for (j = 0; j < n; j++)
        {
            printf (format, matrix [i][j]);
            format = ", %2d";
        }
        puts(" ]");
    }
}

void mtrx_free (size_t m, int **matrix)
{
    register size_t i;

    for (i = 0; i < m; i++)
    {
        free (matrix [i]);
    }
    free (matrix);
}

答案 1 :(得分:-1)

C没有2D数组。它具有数组数组和指针数组,每个数组都可以类似于2D数组使用。不幸的是,realloc()并不知道任何一个。你可以realloc()一个指针数组,然后新的指针将为null并且必须自己分配,并且所有现有的行仍然是旧的大小,并且必须重新分配。您也可以重新分配一个数组数组,但仅当次要维度相同时,也就是说,如果您最初分配了一个10x10数组,则可以将其重新分配为20x10,而不是10x20(或者现有的价值观会转移到奇怪的地方。)

答案 2 :(得分:-2)

由于您没有尝试调整矩阵的大小,而是使用动态维度进行初始化,因此当您知道x和y时,可以通过调用malloc()来执行此操作:

int **global_array;

void main() {

    // ...
    if (allocateMatrixDynamically(3, 5) == 0) {
        // We can now set a value
        global_array[0][0] = 11;
    }
    //...
}

// This functions returns zero if allocation was succesful, and !=0 otherwise
int allocateMatrixDynamically(int rows, int cols) {
    int idxRow, idxCol;
    int RCod = -1;

    // Allocate the memory as requested
    if (rows > 0 && cols > 0) {
        global_array = (int**) malloc(rows * sizeof(int*));
        if (!global_array) {
            return -1;
        }
        for (idxRow=0; idxRow< rows; ++idxRow) {
            global_array[idxRow] =(int*) malloc(cols * sizeof(int));
            if (!global_array[idxRow]) {
                return -1;
            }
        }
    }
    return 0;
}