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
I have created a 2 d array which reads as follows
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);
}
// I allocate a value of 0 to all the elements in this array as below
for(i=0;i<(lx+2)*(ly+2);i++)
{
a[i]=0;
}
// I print out all my elements below
for(i=0;i<(lx+2开发者_运维技巧)*(ly+2);i++)
{
printf("position %d values %d\n",i,a[i]);
}
// When I see the output , it shows me a junk value at one particular position 13. I am unable to figure that out .. ALso kindly tell me how to access rows and columns like Eg to acces 7 th column row 0 and 5th row 6 th column in terms of lx, ly as shown in my code
Your approach is definitely heading in the right general direction.
I think this:
a=(double**) malloc((lx+2)*sizeof(double));
would normally be:
a = malloc(lx * sizeof(double *));
And then without the contiguity requirement, this:
a[0]= (double*) malloc((lx+2)*(ly+2)* sizeof(double));
in most programs would look like:
a[0] = malloc(ly * sizeof(double));
And finally, that last line needs to be in a loop that assigns each a[i]
with it's own malloc'ed space.
However, that won't create contiguous memory. To do that you will need to do that big allocation and then divide it up for the row vector. So, instead of the second malloc in a loop, perhaps something like:
double *t = malloc(lx * ly * sizeof(double));
for (i = 0; i < lx; ++i)
a[i] = t + i * ly;
Putting it all together:
#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
This code allocates a 10 by 5 contiguous block of memory, initializes it with incrementing doubles, and then prints the values indexed by x and 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;
}
The 2d.h file should contain these lines:
#include <stdio.h>
#include <stdlib.h>
int main(void);
Note: The memory created is only contiguous for some definitions. The memory is logically contiguous, but not necessarily physically contiguous. If this memory is for a device driver for instance, malloc won't work.
Either you create a single dimension array
double my_array = malloc(sizeof(double) * size_x * sizeof(double) * size_y);
which you will access by
(get position x=28, y=12)
my_array[12 * size_x + 28];
or you create a 2d array like you do, but you access it with
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];
In C, to have one chunk of contiguous memory, you need one malloc()
, or have a statically allocated array. Since you want dynamic memory, you will need malloc()
. Since you need everything to be contiguous, you will need only one call to it.
Now, what should the call look like? If I understood you correctly, you need lx
times ly
values, each with size sizeof(double)
, so you need lx*ly*sizeof(double)
bytes to be allocated.
Digression: I prefer writing my malloc()
calls as follows:
#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);
Using sizeof
with sizeof *pt
instead of sizeof(T)
offers an advantage that if the type of pt
changes, you don't need to change the malloc()
call. Not casting the result of malloc()
is nice because then the whole malloc()
call is type-agnostic, and is easier to type and read. Be sure to #include <stdlib.h>
though.
So, to allocate space for n
double
s, you can do:
double *pd = malloc(n * sizeof *pd);
if (pd != NULL) {
/* malloc succeeded */
} else {
/* malloc failed */
}
Now, after allocating memory, you need to be able to index it. Let's say you have lx == 2
and ly == 3
. Your memory looks like:
+---+---+---+---+---+---+
pd: | 0 | 1 | 2 | 3 | 4 | 5 |
+---+---+---+---+---+---+
pd[0]
, pd[1]
and pd[2]
are the double
values corresponding to the first row, pd[3]
to pd[6]
are the double
values corresponding to the second row. You should be able to generalize this observation to translate a given x,y
index pair to one number that indexes into your pd
array properly.
精彩评论