如何使用table()
和#Source: local data frame [2 x 3]
#
# A B C
#1 0 4700 5400
#2 1 9400 10800
声明全局变量二维整数数组realloc
然后重新分配一次malloc
和{{1}的数字给出的是int array[][]
?
答案 0 :(得分:0)
在C中模拟2D数组或矩阵时,需要考虑几点。首先要了解实际分配的内容。要模拟您只能通过array[m][n]
访问的2D数组,您要做的是首先为指向int 的指针分配m
指针数组。这提供了m
int*
(或行),您可以分配n
int (列)。
简单地说,您可以分配m pointers to int*
行和n int
列。
现在,在我们查看代码之前,可以选择使用malloc
来分配内存(具体是列)还是使用calloc
。为什么?在您甚至尝试访问数组元素之前,必须初始化该元素以保存某个值。否则,任何尝试从该元素读取的尝试都是尝试从未初始化的值中读取未定义的行为,并且可以将您的程序发送到不归路的地方..
为什么calloc
代替malloc
。 calloc
不仅为您分配空间,还会将该位置的内存初始化/设置为0/NULL
(0
,如果是数字类型,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;
}
分配功能很简单。它接受m
和n
作为参数(类型 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;
}