ç分配的二维整数数组 [英] C allocating 2-dimensional integer array

查看:96
本文介绍了ç分配的二维整数数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我如何使用的realloc 的malloc 来声明一个全局变量2维整数数组说 int数组[] [] 然后重新分配一次号码 X 给出所以它是 int数组[X] [Y]

How do I use realloc and malloc to declare a global variable 2-dimensional integer array say int array[][] then reallocate it once numbers for x and y are given so it is int array[x][y]?

推荐答案

有几个点模拟一个二维数组或矩阵时C.首先了解您实际分配考虑。为了模拟您通过数组[M] [N] ,你正在做的是先分配的数组 M 指针指向int的指针。这提供了 M 为int * (或行),你必须来分配 N INT (列)。

There are several points to consider when simulating a 2D array or matrix in C. First understanding what you are actually allocating. To simulate a 2D array that you access simply by array[m][n], what you are doing is first allocating an array of m pointers to pointer to int. This provides m int* (or rows) which you have available to allocate n int (columns).

所以,简单地说,你分配米的指针为int * ñINT

So simply put, you allocate m pointers to int* rows and n int columns.

现在我们来看看code之前,有一个现实的选择,使您是否使用的malloc 来分配内存(列专),还是你使用释放calloc 。为什么?之前,你甚至可以尝试访问您数组的元素,必须的初始化的元素持有一些价值。否则,任何试图从该元素阅读,是从初始化值读这就是未定义行为企图并可以发送你的程序分拆成不归土地..

Now before we look at the code, there is a practical choice to make on whether you use malloc to allocate the memory (columns specifically) or whether you use calloc. Why? Before you can even attempt to access an element of you array, you must initialize that element to hold some value. Otherwise, any attempt to read from that element, is an attempt to read from an uninitialized value which is undefined behavior and can send your program spinning off into the land of no return..

为什么释放calloc 而不是的malloc 。不仅释放calloc 分配空间给你,它也初始化在该位置内存/设置为 0 /空 0 在指针的情况下,数字类型, NULL 的情况下 - 两者都是有效的 0 )这prevents>从一个未初始化的元素阅读,因为所有的元素都被初始化为 0 0 (或其他)的方式,但往往这是新的C程序员忽视。因此,释放calloc 可帮助保护您免受自己。让我们看一个配置的功能:

Why calloc instead of malloc. Not only does calloc allocate space for you, it also initializes/sets the memory at that location to 0/NULL (0 in the case of a numeric type, NULL in the case of a pointer -- both are effectively 0) This prevents the inadvertent read from an uninitialized element because all elements are initialized to 0 to begin with. Now you are free to set up a loop and set every value to 0 (or whatever) that way, but often this is overlooked by new C programmers. So calloc can help protect you against yourself. Let's look at an allocation function:

/* 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;
}

分配功能是直线前进。它接受 M N 作为参数(键入 为size_t - 索引不能为负),并返回一个完全分配,完全初始化设置 M 指针到ñ阵列 INT 。让我们来看看它的使用分配 my_array 作为一个 4×5 矩阵 INT

The allocation function is straight forward. It accepts m and n as arguments (type size_t -- indexes cannot be negative), and returns a fully allocated, fully initialized set of m pointers to arrays of n int. Let's look at its use to allocate my_array as a 4x5 matrix of int:

int **my_array = mtrx_calloc (4, 5);

在整个你的code的剩余部分,​​您可以通过 my_array访问任何元素[0-3] [0-4] (索引是基于零,只像索引C中的其余部分)

Throughout the remainder of your code, you can access any element by my_array[0-3][0-4] (indexes are zero based, just like the rest of indexing in C)

什么的realloc ?当你谈论固定大小的数组,你需要重新分配内存唯一的一次是,如果你需要调整的数组。 (现在授予你可以只创建一个新的数组和复制新/旧)然而,由于重新分配内存是在C语言中的重要概念,让我们编写一个函数来重新分配行的数目为我们的矩阵。

What about realloc? When you are talking about fixed size arrays, the only time you need to reallocate memory is if you need to resize the array. (Now granted you could just create a new array and copy old/new) However, since reallocating memory is an important concept in C, lets write a function to reallocate the number of rows for our matrix.

比方说,你现在找到你需要的 my_array 8X5 基质代替 4×5 矩阵。在这种情况下,你需要的realloc 指针数为int * 来允许添加<$ C $的C> 4 多行。您还需要分配空间来容纳新值的行 5-8 (指数 4-7 )。

Let's say you now find you need my_array as an 8x5 matrix instead of a 4x5 matrix. In that case you would need to realloc the number of pointers to int* to allow the addition of 4 more rows. You would also need to allocated space to hold the new values for rows 5-8 (indexes 4-7).

您还需要跟踪到你分配的行数,所以如果我们发送一个指向行目前的数量,我们可以更新该地址的价值并获取价值回到我们调用函数(的main()在这种情况下)。我们需要preserve唯一在之前,我们对重新分配调用对于旧值 M (允许填充值的新空间等)我们行的再分配,可以如下所示:

You also need to keep track to the number of rows that you have allocated, so if we send a pointer to the current number of rows, we can update the value at that address and have the value available back in our calling function (main() in this case). The only thing we would need to preserve in main before we make the call to reallocate is the old value for m (to allow filling the new space with values, etc.) Our reallocation of rows could look like the following:

/* 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 ,这将导致如果我们的数据完全丢失我们已经指派的realloc 返回到我们的数组。通过使用 TMP 数组,那么你有灵活性,需要处理的失败。示例调用重新分配4个额外的行看起来像:

Now it is important to notice, that we do not directly assign the newly reallocated value to our array variable, but instead to a tmp variable. Why? If the reallocation fails, realloc frees the newly allocated space returns NULL, which would cause a complete loss of our data if we had assigned the return of realloc to our array. By using a tmp array instead, you have the flexibility to handle a failure as required. A sample call to reallocate 4 additional rows would look like:

my_array = realloc_rows (my_array, &m, n, m + 4);

这是更长的一个二维矩阵/阵列比我最初打算的概述,但也有很多的考虑是进入连一套简单的函数来处理动态地分配和重新分配的模拟二维数组。就这样,我们会留下一个例子来看看。这个例子将默认创建一个3x4的二维数组,但你也可以指定大小作为参数传递给程序。例如:

That's much longer an overview of a 2D matrix/array than I initially intended, but there are a lot of considerations that go into even a simple set of functions to handle dynamically allocating and reallocating a simulated 2D array. With that, we will leave you with an example to look at. The example will create a 3x4 2D array by default, but you can also specify the size as arguments to the program. For example:

./programname 4 5

将创造而不是默认的初始4X5的二维数组。要显示使用realloc的,无论大小最初分配将被调整为与其他值添加4行和填充新行。无论是原来的大小和重新分配大小的数组打印到标准输出。让我知道如果您有任何疑问:

Will create an initial 4x5 2D array, instead of the default. To show the use of realloc, whatever size is initially allocated will be resized to add 4 rows and fill the new rows with miscellaneous values. Both the original size and the reallocated size arrays are printed to stdout. Let me know if you have questions:

/*
    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);
}

创建4x5的矩阵和重新分配给8X5

$ ./bin/mtrx_dyn_int 4 5

The dynamically allocated 4x5 matrix is:

[  0,  1,  2,  3,  4 ]
[  1,  2,  3,  4,  5 ]
[  2,  3,  4,  5,  6 ]
[  3,  4,  5,  6,  7 ]

Reallocate matrix to 8x5:

[  0,  1,  2,  3,  4 ]
[  1,  2,  3,  4,  5 ]
[  2,  3,  4,  5,  6 ]
[  3,  4,  5,  6,  7 ]
[  4,  5,  6,  7,  8 ]
[  5,  6,  7,  8,  9 ]
[  6,  7,  8,  9, 10 ]
[  7,  8,  9, 10, 11 ]

查看内存错误/泄漏

$ valgrind ./bin/mtrx_dyn_int 4 5
==31604== Memcheck, a memory error detector
==31604== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==31604== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==31604== Command: ./bin/mtrx_dyn_int 4 5
==31604==

The dynamically allocated 4x5 matrix is:

[  0,  1,  2,  3,  4 ]
[  1,  2,  3,  4,  5 ]
[  2,  3,  4,  5,  6 ]
[  3,  4,  5,  6,  7 ]

Reallocate matrix to 8x5:

[  0,  1,  2,  3,  4 ]
[  1,  2,  3,  4,  5 ]
[  2,  3,  4,  5,  6 ]
[  3,  4,  5,  6,  7 ]
[  4,  5,  6,  7,  8 ]
[  5,  6,  7,  8,  9 ]
[  6,  7,  8,  9, 10 ]
[  7,  8,  9, 10, 11 ]

==31604==
==31604== HEAP SUMMARY:
==31604==     in use at exit: 0 bytes in 0 blocks
==31604==   total heap usage: 10 allocs, 10 frees, 256 bytes allocated
==31604==
==31604== All heap blocks were freed -- no leaks are possible
==31604==
==31604== For counts of detected and suppressed errors, rerun with: -v
==31604== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

这篇关于ç分配的二维整数数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆