如何分配具有连续内存的二维数组?如何使用它来访问行和列?给我一个例子
Posted
技术标签:
【中文标题】如何分配具有连续内存的二维数组?如何使用它来访问行和列?给我一个例子【英文标题】:How do I allocate a 2 D array with contigious memory ? How Do I use it to access rows and columns? Give me an example 【发布时间】:2011-01-16 14:47:30 【问题描述】:我创建了一个二维数组,内容如下
int i,j,lx,ly;// lx,ly are the row and column respectively
double** a;
a=(double**) malloc((lx+2)*sizeof(double));
a[0]= (double*) malloc((lx+2)*(ly+2)* sizeof(double));
assert(a[0]);
for(i=1;i<lx+2;i++)
a[i]=a[i-1]+i*(ly+2);
//我为这个数组中的所有元素分配一个值0,如下所示
for(i=0;i<(lx+2)*(ly+2);i++)
a[i]=0;
// 我打印出下面的所有元素
for(i=0;i<(lx+2)*(ly+2);i++)
printf("position %d values %d\n",i,a[i]);
// 当我看到输出时,它在一个特定位置 13 处显示了一个垃圾值。我无法弄清楚.. 还请告诉我如何访问行和列,例如 Eg 以访问第 7 列行0 和第 5 行第 6 列以 lx 表示,ly 如我的代码所示
【问题讨论】:
这是什么? a[0]= (double*) malloc((lx+2)*(ly+2)* sizeof(double));这不是初始化数组第二维的方式。 我标记了这个c
,如果我错了就改。该站点适用于所有编程活动,大多数读者在这里根本不使用 C。使用有意义的标签帮助可以帮助您找到问题的人。
这看起来有点像家庭作业。你能解释一下lx和ly吗?它们似乎没有被初始化。
嗨,约翰,这是一个非常重要的家庭作业,但也是其中的一部分。我需要学习如何使用连续的二维数组来完成整个任务。
【参考方案1】:
在 C 中,要拥有一块连续的内存,您需要一个 malloc()
,或者拥有一个静态分配的数组。由于您需要动态内存,因此您需要malloc()
。由于您需要所有内容都是连续的,因此您只需要 一个 调用它。
现在,调用应该是什么样的?如果我理解正确,您需要lx
乘以ly
值,每个值的大小为sizeof(double)
,因此您需要分配lx*ly*sizeof(double)
字节。
题外话:我更喜欢这样写我的malloc()
调用:
#include <stdlib.h> /* for malloc's prototype */
T *pt; /* for any type T */
size_t n; /* need n objects of type T */
pt = malloc(n * sizeof *pt);
将sizeof
与sizeof *pt
一起使用而不是sizeof(T)
的优势在于,如果pt
的类型发生变化,您无需更改malloc()
调用。不转换malloc()
的结果很好,因为整个malloc()
调用与类型无关,并且更易于键入和阅读。不过请务必#include <stdlib.h>
。
所以,要为n
double
s 分配空间,你可以这样做:
double *pd = malloc(n * sizeof *pd);
if (pd != NULL)
/* malloc succeeded */
else
/* malloc failed */
现在,在分配内存之后,您需要能够对其进行索引。假设您有lx == 2
和ly == 3
。你的记忆是这样的:
+---+---+---+---+---+---+
pd: | 0 | 1 | 2 | 3 | 4 | 5 |
+---+---+---+---+---+---+
pd[0]
、pd[1]
和pd[2]
是第一行对应的double
值,pd[3]
到pd[6]
是第二行对应的double
值。您应该能够概括此观察结果,将给定的x,y
索引对转换为正确索引到您的pd
数组中的一个数字。
【讨论】:
【参考方案2】:此代码分配一个 10 x 5 的连续内存块,用递增的双精度数对其进行初始化,然后打印由 x 和 y 索引的值:
#include "2d.h"
int main(void)
unsigned int x,y;
const unsigned int width = 10;
const unsigned int height = 5;
//we need an index into the x of the array
double * index[width];
//need the memory to store the doubles
unsigned int memorySizeInDoubles = width * height;
double * memory = malloc(memorySizeInDoubles * sizeof(double));
//initialize the memory with incrementing values
for(x = 0; x < memorySizeInDoubles; ++x)
memory[x] = (double) x;
//initialize the index into the memory
for(x = 0; x < width; ++x)
index[x] = memory + height * x;
//print out how we did
for(x = 0; x < width; ++x)
for(y = 0; y < height; ++y)
printf("[%u, %u]: Value = %f\n", x, y, index[x][y]);
free(memory);
return 0;
2d.h 文件应包含以下行:
#include <stdio.h>
#include <stdlib.h>
int main(void);
注意:创建的内存仅对某些定义是连续的。内存在逻辑上是连续的,但不一定在物理上是连续的。例如,如果此内存用于设备驱动程序,则 malloc 将不起作用。
【讨论】:
【参考方案3】:您的方法肯定朝着正确的大方向前进。
我认为是这样的:
a=(double**) malloc((lx+2)*sizeof(double));
通常是:
a = malloc(lx * sizeof(double *));
然后没有连续性要求,这个:
a[0]= (double*) malloc((lx+2)*(ly+2)* sizeof(double));
在大多数程序中看起来像:
a[0] = malloc(ly * sizeof(double));
最后,最后一行需要在一个循环中,为每个 a[i]
分配它自己的 malloc'ed 空间。
但是,这不会创建连续的内存。为此,您需要进行大分配,然后将其划分为行向量。因此,而不是循环中的第二个 malloc,可能类似于:
double *t = malloc(lx * ly * sizeof(double));
for (i = 0; i < lx; ++i)
a[i] = t + i * ly;
把它们放在一起:
#include <stdio.h>
#include <stdlib.h>
void arrayDemo(int lx, int ly)
double **a;
int i, j;
a = malloc(lx * sizeof(double *));
double *t = malloc(lx * ly * sizeof(double));
for(i = 0; i < lx; ++i)
a[i] = t + i * ly;
for(i = 0; i < lx; ++i)
for(j = 0; j < ly; ++j)
a[i][j] = i*100 + j;
for(i = 0; i < lx; ++i)
for(j = 0; j < ly; ++j)
printf(" %4.0f", a[i][j]);
printf("\n");
int main(int ac, char **av)
arrayDemo(atoi(av[1]), atoi(av[2]));
return 0;
$ cc -Wall all.c
$ ./a.out 4 7
0 1 2 3 4 5 6
100 101 102 103 104 105 106
200 201 202 203 204 205 206
300 301 302 303 304 305 306
【讨论】:
HI 使用 2 个 malloc 不会给我一个连续的记忆,对吧?我期待的是一个连续的记忆......因此有没有什么机制可以做到这一点? 是的,有时 SO 会奖励增量答案,抱歉耽搁了。 :-) 最后一行有效,因为首先评估i * lx
然后变为 pointer + int 导致 int 按对象大小缩放。
嗨,第二个代码看起来很酷。你能详细说明一下吗?这就是我所理解的......我只是让 [i] 指向数组中的每一行正确吗?现在我需要做什么来访问相同的,以填充行和列中的值。提前感谢您的快速回复。
如果我这样做会发生什么? a=(double*) malloc((lx+2)*(ly+2)*sizeof(double)); for(i=0;i
即使在我的最后一个示例中,您仍然需要第一个 malloc,它分配指向原始行的指针向量。因此,您可以使用a[i][j]
访问该数组。所以也许for(i=0; i<lx; ++i) for (j=0; j<ly; ++j) a[i][j] = 0.0;
【参考方案4】:
要么你创建一个单维数组
double my_array = malloc(sizeof(double) * size_x * sizeof(double) * size_y);
你将通过它访问
(获取位置 x=28, y=12)
my_array[12 * size_x + 28];
或者你像你一样创建一个二维数组,但是你使用
double **my_array = (double**) malloc(15 * sizeof(double));
for(int i = 0 ; i < 25; i++)
my_array[i] = (double*) malloc(30 * sizeof(double));
for (int j = 0 ; j < 12; j++)
my_array[i][j] = 1.2;
double my_double = my_array[12][28];
【讨论】:
HI 使用 2 个 malloc 不会给我一个连续的记忆,对吧?我期待的是一个连续的记忆......因此有什么机制可以做到这一点? @srinivasavaradan,这里的第一个答案给你连续的记忆。 哦,那我猜应该是 double * my_array = malloc(sizeof(double) * size_x * sizeof(double) * size_y); // 我说的对吗? 在声明 my_array 时是否遗漏了 * @srinivassavaradan,是的,那里似乎缺少*
。以上是关于如何分配具有连续内存的二维数组?如何使用它来访问行和列?给我一个例子的主要内容,如果未能解决你的问题,请参考以下文章