Thread: pointer to array with dynamic allocation

  1. #1
    Registered User
    Join Date
    Mar 2009
    Posts
    114

    pointer to array with dynamic allocation

    Hi there,

    I need to change a static allocation of a pointer defined as shown in Code (1) into a dynamic-type allocation.
    Specifically, in that described in (1) I am able to assign *vars[] because variable1 is already statically allocated, but for my work I do not know the size of variable1 until a subsequent dynamic allocation that will occur throughout the code, giving me a problem in assigning *vars[] at the beginning.
    Also, *vars[] will not contain only variable1, but a series of variables where the amount of these variables is also decided only inside the code.

    Is anyone able to help? I hope I made the questioning clear; if this is not the case, please ask me more of what you need.

    Thank you in advance
    All the best

    Code (1):
    Code:
    float variable1[n][m];
    float *vars[] = {(float*)variable1};
    Cose(2): What I need to obtain:
    Code:
    //Declaration of matrix "variable":
    float **variable;
    
    //Dynamic allocation of **variable through the code after getting the value of m and n:
    variable = matrix(0,m, 0,n);
    
    //Now I want to finally assign *vars[] with the new allocated variable1, but I 
    //do not know how to do this by using a formulation similar to:
    float *vars[] = {(float*)variable1};

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    If you don't know either dimension until run time, then you need to use multiple allocations.

    Code:
    float **variable = malloc(sizeof(float *)*m);
    for (int i = 0; i < m; ++i)
       variable[i] = malloc(sizeof(float)*n);
    Naturally, your eventual calls to free() need to be in reverse order from the allocations.

    Of, if you want the array to be contiguous....
    Code:
    float *variable = malloc(sizeof(float)*m*n);
    although, with this, you access elements differently (eg variable[i*m + j])
    Last edited by grumpy; 04-06-2009 at 05:03 AM.

  3. #3
    Registered User
    Join Date
    Mar 2009
    Posts
    114
    Hi, the problem is not in allocating variable1, but in assigning *vars[] with variable one as one of its elements during executation.

    variable1 is already adynamically allocated in the correct way, the problem comes when I want this to be done:

    Code:
    float *vars[] = {(float*) variable1};
    thank you again
    CFD

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    That doesn't make sense. What do you intend vars to represent?

  5. #5
    Registered User
    Join Date
    Mar 2009
    Posts
    114
    Hi,

    An original code that I need to modify does the following:

    Code:
    float variable1[n][m];
    float variable2[k][l];
    float *vars[] = {(float*)variable1, (float*)variable2};
    now, I need to do pretty much the same, but in such a way that I can assign vars with a set of variables whose dimension is only known by dynamic allocation of them later.
    That is why I need to change the above definitions and assignment in such a way that I can still build *vars[] as above, but by using variable1 and variable2 after they have been dynamically allocated. That would imply also allocating dynamically *vars[], which, at this point, is not done iether

    thank you again,
    All the best

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    OK; that "original code" presumably relies on local arrays (eg your variable1) being continguous in memory. i.e. the end of one row and the start of the next are adjacent in memory.

    The way you need to do this is;
    Code:
        float *variable1 = malloc(sizeof(float)*n*m);
        float *variable2 = malloc(sizeof(float)*k*l);
        float *vars[2] = {variable1, variable2};
        vars[0][i*n + j] = 6;   // set an element of variable1
        vars[1][i*k + j] = 42;  // set an element of variable2
    The catch with this is that you can't use the 2D array syntax to access elements of variable1 (i.e. you can't access elements as variable1[i][j] - you need to treat it like a 1D array). 2D array syntax relies on all but the first dimension being known at compile time - and you presumably want to get away from that constraint.

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I'm pretty sure that the posted code doesn't actually work as expected - I may be wrong, but I'm of the opinion that a 2D array can not ever be made into a double pointer structure without a loop of some sort to fill in each pointer level. The posted code will work OK if the rest of the code simply uses this as a 1D array, but not if it's used as a 2D array.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    Registered User
    Join Date
    Mar 2009
    Posts
    114
    Hi there to both; both answers are helpful, and to confirm what you say, yes, the array that will be used (*vars[]) is goin to be used as a 1D array indeed.

    The only thing I needed to get done right was the assignment of *vars[] given that its elements (variable1, variable2, etc) will be allocated dynamically at some point of the code.

    I will test your reply before today and will let you know whether it worked as I expected it to.

    Thank you again
    All the best
    CFD

  9. #9
    Registered User
    Join Date
    Mar 2009
    Posts
    114
    Hi again, I am lost about how the memory is allocated by using the syntax explained in this thread.
    Specifically, to give a summary, I tried to allocate memory in such a way that would be EQUIVALENT to a static allocation given by the following:

    Code:
    #define NX 5
    #define NY 4
    
    float zonal[NY-1][NX-1];
    float *variables[] = {(float*)zonal}
    but, since the number of entries for variables can change during execution (I may not only have zonal, but also other variables, and the number of this variables will be known only at a certain point of the code), I tried to do the following:

    Code:
    #define NX 5
    #define NY 4
    
    int i,j,k;
    
    float zonal[NY-1][NX-1];
    
    int nvars; //unknown at this time
    float **variables;
    
    //Dyn. Allocation (done in 2 steps):
    nvars = 1; //this number can change! that is why I need dynamic allocation
    
    variables = (float**) malloc(nvars* sizeof(float));
    for(i=0; i<nvars; i++){
    	variables[i] = (float*) malloc( NX*NY * sizeof(float));
    
    //Assign zonal[][] simply as a 2D array, e.g.:
    for(j = 0; j < NY-1; ++j) 
    	for(i = 0; i < NX-1; ++i, ++index) 
    		zonal[j][i] = (float)(i+j);
    
    
    //And I finally assigned (tried to) "variables[][]" with
    k=0;
    for(j = 0; j < NY; ++j){
    	for(i = 0; i < NX; ++i){
    		variables[0][k] = zonal[j][i];
    		k++;
    	}
    }
    but this last assignment results to be wrong, in fact, it assigns variables with the wrong numbers in the wrong position.

    How is this last assignment supposed to be done in order to be equivalent to the static version:
    Code:
    float *variables[] = {(float*)zonal}
    ?

    Thank you very much again
    CFD

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    So how is variables in the original code used?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  11. #11
    Registered User
    Join Date
    Mar 2009
    Posts
    114
    Hi Mat,

    In the original code it's very simple actually; this is the way it's done:

    Code:
    //[1] General Declarations:
    #define NY 5
    #define NX 4
    
    int i,j,k,index;
    
    //[2] Declaration of zonal[][]:
    float zonal[NY-1][NX-1];
    
    
    //[3] Declaration + Assignment of *variables[]:
    float *variabless[] = {(float*)zonal};
    
    //[4] Assignment of zonal[][]:
    for(j = 0; j < NY-1; ++j) 
    	for(i = 0; i < NX-1; ++i, ++index) 
    		zonal[j][i] = (float)index;
    
    //At this point *variables[] was already assigned as in [4], and nothing else is done.
    Its values are now written to a file.
    Thank you for replying

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    So, all you want to do is write the values from your zonal to disk, but it's done as one write?

    If so, I think you will need to teach the write functionality to deal with discontiguous memory, since all your arrays will not be from the same block of memory. Which also (most likely) means that you have to do something slightly differently about telling it where to fetch the data from, and the current suggested structure doesn't seem quite right.

    Edit: It may help if we get to see the write-to-file function too!

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  13. #13
    Registered User
    Join Date
    Mar 2009
    Posts
    114
    Quote Originally Posted by matsp View Post
    So, all you want to do is write the values from your zonal to disk, but it's done as one write?

    If so, I think you will need to teach the write functionality to deal with discontiguous memory, since all your arrays will not be from the same block of memory. Which also (most likely) means that you have to do something slightly differently about telling it where to fetch the data from, and the current suggested structure doesn't seem quite right.
    I don't really know how to do it. Would you be able to help?

    Edit: It may help if we get to see the write-to-file function too!
    the function that writes to file is a little of a mess, I report an extrapolation of it that is the core part I would say:

    Code:
    for(i=0; i<nvars; i++){
    
           int num_to_write = ncells*vardim[i]; 
                    for (j = 0 ; j < num_to_write ; j++)
                    {
                        write_float(vars[i][j]);
                    }
    }
    where "write_float" is the following:

    Code:
    static void write_float(float val)
    {
        if (useBinary)
        {
            force_big_endian((unsigned char *) &val);
            fwrite(&val, sizeof(float), 1, fp);
        }
        else
        {
            char str[128];
            sprintf(str, "%20.12e ", val);
            fprintf(fp, str);
            if (((numInColumn++) % 9) == 8)
            {
                end_line();
            }
        }
    }
    thank you

  14. #14
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    You do realize, I take it, that zonal[NY-1][NX-1] is a different size 2D array than what you malloc? NX * NY is not the same as (NX-1) * (NY-1)...

    I'm perfectly happy to try to help you, but somtimes it is hard when you don't know what's wrong.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  15. #15
    Registered User
    Join Date
    Mar 2009
    Posts
    114
    Quote Originally Posted by matsp View Post
    You do realize, I take it, that zonal[NY-1][NX-1] is a different size 2D array than what you malloc? NX * NY is not the same as (NX-1) * (NY-1)...
    Hi Mat, yes, actually I know that the numbers are different, but I dont expect it to be the error, no? After all, can't allocate as much memory as I want independently on what I want to assign it with (as long as I assign it with less or equal the amount that is allocated) ?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. sorting the matrix question..
    By transgalactic2 in forum C Programming
    Replies: 47
    Last Post: 12-22-2008, 03:17 PM
  2. Quick Pointer Question
    By gwarf420 in forum C Programming
    Replies: 15
    Last Post: 06-01-2008, 03:47 PM
  3. pointer of array of class
    By 11moshiko11 in forum C++ Programming
    Replies: 5
    Last Post: 04-05-2008, 09:58 AM
  4. Pros pls help, Pointer to array
    By kokopo2 in forum C Programming
    Replies: 7
    Last Post: 08-17-2005, 11:07 AM
  5. sending or recieving a[][]to a function
    By arian in forum C++ Programming
    Replies: 12
    Last Post: 05-01-2004, 10:58 AM