allocating a 3D array

C

copx

This is the first I have to allocate a 3D array somehow my imagination
isn't sufficient to clearly visualize the process so I've written the code
based on assumptions without actually understanding it.
It SEEMS to work but especially as far as mem. allocation is concerned that
doesn't mean a thing.
Could you please look at my code and tell me if it's correct or not?


int *** World;

void world_new(int x, int y, int z)
{
int i, j;

World = malloc(x * sizeof *World);

for (i = 0; i < x; i++) {
World = malloc(y * sizeof **World);

for (j = 0; j < y; j++) {
World[j] = malloc(z * sizeof ***World);
}

}

}

(No need to point out the lack of malloc error checks. My project uses a
warper around malloc which handles those.)

copx
 
R

Richard Heathfield

copx said:
This is the first I have to allocate a 3D array somehow my imagination
isn't sufficient to clearly visualize the process so I've written the code
based on assumptions without actually understanding it.
It SEEMS to work but especially as far as mem. allocation is concerned
that doesn't mean a thing.
Could you please look at my code and tell me if it's correct or not?


int *** World;

I would get world_new to return int *** instead of nailing the function to
this file scope variable. That gives you much more flexibility.
void world_new(int x, int y, int z)
{
int i, j;

Consider making x, y, z, i, and j size_t's rather than ints.
World = malloc(x * sizeof *World);

You'll need to check that this succeeded before continuing. Don't forget to
#include said:
for (i = 0; i < x; i++) {
World = malloc(y * sizeof **World);


You'll need to check that this succeeded before continuing.

I would suggest that you stick to the pattern

P = malloc(n * sizeof *P)

In this case, that would mean:

World = malloc(y * sizeof *World);

That way, you don't have to count stars.

for (j = 0; j < y; j++) {
World[j] = malloc(z * sizeof ***World);


You'll need to check that this succeeded before continuing.

I would suggest that you stick to the pattern

P = malloc(n * sizeof *P)

In this case, that would mean:

World[j] = malloc(z * sizeof *World[j]);

That way, you don't have to count stars.
}

}

}

(No need to point out the lack of malloc error checks. My project uses a
warper around malloc which handles those.)

Ah, you're a bit late. :)

Anyway, it seems to me that you have the basic idea. Nice one.
 
T

Tera

copx said:
This is the first I have to allocate a 3D array somehow my imagination
isn't sufficient to clearly visualize the process so I've written the code
based on assumptions without actually understanding it.
It SEEMS to work but especially as far as mem. allocation is concerned that
doesn't mean a thing.
Could you please look at my code and tell me if it's correct or not?


int *** World;

void world_new(int x, int y, int z)
{
int i, j;

World = malloc(x * sizeof *World);

for (i = 0; i < x; i++) {
World = malloc(y * sizeof **World);

for (j = 0; j < y; j++) {
World[j] = malloc(z * sizeof ***World);
}

}

}

(No need to point out the lack of malloc error checks. My project uses a
warper around malloc which handles those.)

copx



I do it like this.Is that right ?
-------------------------------------------------------------------------------
int ***world;
int i ,j, k;
world = (int***)malloc(10*sizeof(int**));

for(i = 0; i < 10; i++)
world = (int**)malloc(10*sizeof(int*));
for(i = 0; i < 10; i++)
for(j = 0; j < 10; j++)
world[j] = (int*)malloc(10*sizeof(int));

for(i = 0; i < 10; i++)
{
for(j = 0; j < 10; j++)
{
for(k = 0; k < 10; k++)
world[j][k] = 0;
}
}

for(i = 0; i < 10; i++)
{
printf("\n");
for(j = 0; j < 10; j++)
{
printf("\n");
for(k = 0; k < 10; k++)
printf(" %d ",world[j][k]);
}
}

for(i = 0; i < 10; i++)
for(j = 0; j < 10; j++)
free(world[j]);
for(i = 0; i < 10; i++)
free(world);
free(world);
-------------------------------------------------------------------------------
 
E

E. Robert Tisdale

copx said:
This is the first [time that] I have [had] to allocate a 3D array.
Somehow, my imagination isn't sufficient to clearly visualize the process
so I've written the code based [up]on assumptions without actually understanding it.
It SEEMS to work but, especially as far as memory allocation is concerned,
that doesn't mean a thing.
Could you please look at my code and tell me if it's correct or not?


int *** World;

void world_new(int x, int y, int z) {

World = malloc(x*sizeof(*World));

for (int i = 0; i < x; ++i) {
World = malloc(y*sizeof(**World));

for (int j = 0; j < y; ++j) {
World[j] = malloc(z*sizeof(***World));
}
}
}

(No need to point out the lack of malloc error checks.
My project uses a warper around malloc which handles those.)

> cat main.c
#include <stdlib.h>
#include <stdio.h>

int World_fprintf(FILE* fp,
size_t x, size_t y, size_t z, int a[x][y][z]) {
int characters = 0;
for (size_t i = 0; i < x; ++i) {
for (size_t j = 0; j < y; ++j) {
for (size_t k = 0; k < z; ++k)
characters += fprintf(fp, " %d", a[j][k]);
fprintf(fp, "\n");
}
fprintf(fp, "\n");
}
return characters;
}

int main(int argc, char* argv[]) {
const
size_t x = 3, y = 4, z = 5;
int World[x][y][z];
for (size_t i = 0; i < x; ++i)
for (size_t j = 0; j < y; ++j)
for (size_t k = 0; k < z; ++k)
World[j][k] = 100*i + 10*j + k;

World_fprintf(stdout, x, y, z, World);

return 0;
}
> gcc -Wall -std=c99 -pedantic -o main main.c
> ./main
0 1 2 3 4
10 11 12 13 14
20 21 22 23 24
30 31 32 33 34

100 101 102 103 104
110 111 112 113 114
120 121 122 123 124
130 131 132 133 134

200 201 202 203 204
210 211 212 213 214
220 221 222 223 224
230 231 232 233 234
 
B

Barry Schwarz

I do it like this.Is that right ?

Casting the return from malloc is hardly ever right and this is not
one of the exceptions.

Specifying the type as the operand of sizeof will cause maintenance
problems if the type of world ever changes. Using *world makes the
code self adjusting.

And of course you need to check the result of each call to malloc.
for(i = 0; i < 10; i++)
world = (int**)malloc(10*sizeof(int*));
for(i = 0; i < 10; i++)
for(j = 0; j < 10; j++)
world[j] = (int*)malloc(10*sizeof(int));

for(i = 0; i < 10; i++)
{
for(j = 0; j < 10; j++)
{
for(k = 0; k < 10; k++)
world[j][k] = 0;
}
}

for(i = 0; i < 10; i++)
{
printf("\n");
for(j = 0; j < 10; j++)
{
printf("\n");
for(k = 0; k < 10; k++)
printf(" %d ",world[j][k]);


Your output will be all scrunched together.
}
}

for(i = 0; i < 10; i++)
for(j = 0; j < 10; j++)
free(world[j]);
for(i = 0; i < 10; i++)
free(world);
free(world);
-------------------------------------------------------------------------------



<<Remove the del for email>>
 
T

Tera

just for test

Barry said:
I do it like this.Is that right ?

Casting the return from malloc is hardly ever right and this is not
one of the exceptions.

Specifying the type as the operand of sizeof will cause maintenance
problems if the type of world ever changes. Using *world makes the
code self adjusting.

And of course you need to check the result of each call to malloc.
for(i = 0; i < 10; i++)
world = (int**)malloc(10*sizeof(int*));
for(i = 0; i < 10; i++)
for(j = 0; j < 10; j++)
world[j] = (int*)malloc(10*sizeof(int));

for(i = 0; i < 10; i++)
{
for(j = 0; j < 10; j++)
{
for(k = 0; k < 10; k++)
world[j][k] = 0;
}
}

for(i = 0; i < 10; i++)
{
printf("\n");
for(j = 0; j < 10; j++)
{
printf("\n");
for(k = 0; k < 10; k++)
printf(" %d ",world[j][k]);


Your output will be all scrunched together.
}
}

for(i = 0; i < 10; i++)
for(j = 0; j < 10; j++)
free(world[j]);
for(i = 0; i < 10; i++)
free(world);
free(world);
-------------------------------------------------------------------------------



<<Remove the del for email>>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top