allocating a 3D array

Discussion in 'C Programming' started by copx, Sep 14, 2005.

  1. copx

    copx Guest

    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
    copx, Sep 14, 2005
    #1
    1. Advertising

  2. 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 <stdlib.h> for the malloc prototype.

    >
    > 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.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/2005
    http://www.cpax.org.uk
    email: rjh at above domain
    Richard Heathfield, Sep 14, 2005
    #2
    1. Advertising

  3. copx

    copx Guest

    "Richard Heathfield" <> schrieb im Newsbeitrag
    news:dg8ddl$fh2$-infra.bt.com...
    [snip]
    >Anyway, it seems to me that you have the basic idea. Nice one.


    Thanks.

    copx
    copx, Sep 14, 2005
    #3
  4. copx

    Tera Guest

    copx wrote:
    > 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);
    -------------------------------------------------------------------------------
    Tera, Sep 23, 2005
    #4
  5. copx wrote:

    > 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
    E. Robert Tisdale, Sep 23, 2005
    #5
  6. On 23 Sep 2005 02:06:49 -0700, "Tera" <> wrote:

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


    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>>
    Barry Schwarz, Sep 24, 2005
    #6
  7. copx

    Tera Guest

    just for test

    Barry Schwarz wrote:
    > On 23 Sep 2005 02:06:49 -0700, "Tera" <> wrote:
    >
    > >I do it like this.Is that right ?
    > >-------------------------------------------------------------------------------
    > > int ***world;
    > > int i ,j, k;
    > > world = (int***)malloc(10*sizeof(int**));

    >
    > 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>>
    Tera, Sep 24, 2005
    #7
  8. On 24 Sep 2005 06:11:07 -0700, "Tera" <> wrote:

    >
    >just for test
    >

    snip 60 lines

    Did you need to quote all that?


    <<Remove the del for email>>
    Barry Schwarz, Sep 24, 2005
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Philipp
    Replies:
    21
    Views:
    719
    White Wolf
    Sep 17, 2003
  2. modemer

    allocating array in function

    modemer, Mar 15, 2005, in forum: C++
    Replies:
    5
    Views:
    2,749
    Karl Heinz Buchegger
    Mar 16, 2005
  3. Chris Lambacher
    Replies:
    0
    Views:
    374
    Chris Lambacher
    Jun 8, 2005
  4. Chris Lambacher
    Replies:
    0
    Views:
    663
    Chris Lambacher
    Jun 8, 2005
  5. Rakesh Kumar
    Replies:
    5
    Views:
    670
    James Kanze
    Dec 21, 2007
Loading...

Share This Page