Thread: pointer to array with dynamic allocation

Hybrid View

Previous Post Previous Post   Next Post Next Post
  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
    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.

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

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

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

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