#1
  1. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Location
    India
    Posts
    65
    Rep Power
    20

    Question How to allocate memory to double pointer("**") ?


    Dear Friends,
    How to allocate memory with double pointer ?

    Following code will explain you better.
    Code:
    int *pointer1;
    int **pointer2=pointer1;
    Now what if i want to allocate memory to pointer1 by malloc ?
    Will it be like this ? I have tried but not worked. Suggest me a way to allocate memory to pointer1 by pointer2.
    Code:
    pointer2=(int **)malloc(sizeof(int));
  2. #2
  3. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    Your first code is wrong. If you tried to compile a program with that in it, you would get a warning or error message complaining about incompatible pointer types or different levels of indirection. This, however, would be correct:
    Code:
    int *pointer1;
    int **pointer2 = &pointer1;
    pointer2 points to pointer1, which itself points to an int value.

    As presented, you shouldn't malloc for pointer2, but rather for pointer1; ie:
    Code:
        int *pointer1;
        int **pointer2 = &pointer1;
    
        pointer1 = (int *)malloc(sizeof(int));
    Now the question is: what do you eventually want to do with that int** ? Are you thinking about creating a two-dimensional array dynamically? Or is it something else? Or are you just playing around with pointers trying to understand them?

    If you're trying to understand pointers, then there was a two-part article written in the 1990's that would help. I've even quoted from it recently to help 2001goran (look for the thread he started). Here's the recommendation I had written about the articles in an earlier thread (editted to omit the links where you'd have to pay for the download):
    Originally Posted by dwise1_aol
    This exercise in multiple levels of indirection (ie, pointer to a pointer to a pointer ... ) had reminded me of an excellent pair of articles written many years ago in the C Users Journal. I just found a copy in my files:
    Pointer Power in C and C++, Parts 1 and 2 by Christopher Skelly, The C Users Journal, Feb and Mar 1993.

    If your college/university library has that magazine in its periodicals section, then burn a copy for yourself. If not, then I found it on-line by Google'ing on "Pointer Power in C and C++" "Christopher Skelly" for other options. For example, I found the articles re-posted at http://collaboration.cmc.ec.gc.ca/sc...lly/skelly.htm (Part 1) and at http://collaboration.cmc.ec.gc.ca/sc...lly/skelly.htm (Part 2).

    You can print those pages or save them, for free.

    Share and enjoy!
    Skelly had based those articles on ten years experience teaching C and on materials he had developed for teaching pointers. His approach is good for thinking about indirection (which is what pointers is all about) and working with different levels of indirection. Good supplemental material.
    Last edited by dwise1_aol; May 20th, 2013 at 12:01 PM.
  4. #3
  5. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,841
    Rep Power
    480
    I recommend my allocarray.
    Originally Posted by me
    Allocates arbitrary dimensional arrays (and inits all pointers) with only 1 call to malloc.
    Code:
    /*
      compilation with embedded example function, assuming this file is named allocarray.c
    
      cc -Wall -DCOMPILE_EXAMPLE -c -o ./allocarray ./allocarray.c
    */
    
    #include<stdlib.h>
    #include<stdio.h>
    
    static void error(int status, char*message) {
      fprintf(stderr,"\n%s\n",message);
      exit(status);
    }
    
    static void*dwlcalloc(int n,size_t bytes) {
      void*rv = (void*)calloc(n,bytes);
      if (NULL == rv)
        error(1, "memory allocation failure");
      return rv;
    }
    
    void*allocarray(size_t rank,size_t*shape,size_t itemSize) {
      /*
         Allocates arbitrary dimensional arrays (and inits all pointers)
         with only 1 call to malloc.  Lambert Electronics, USA, NY.
         This is wonderful because one only need call free once to deallocate
         the space.  Special routines for each size array are not need for
         allocation of for deallocation.  Also calls to malloc might be expensive
         because they might have to place operating system requests.  One call
         seems optimal.
      */
      size_t size,i,j,dataSpace,pointerSpace,pointers,nextLevelIncrement;
      char*memory,*pc,*nextpc;
      if (rank < 2) {
        if (rank < 0)
          error(1,"invalid negative rank argument passed to allocarray");
        size = rank < 1 ? 1 : *shape;
        return dwlcalloc(size,itemSize);
      }
      pointerSpace = 0, dataSpace = 1;
      for (i = 0; i < rank-1; ++i)
        pointerSpace += (dataSpace *= shape[i]);
      pointerSpace *= sizeof(char*);
      dataSpace *= shape[i]*itemSize;
      memory = pc = dwlcalloc(1,pointerSpace+dataSpace);
      pointers = 1;
      for (i = 0; i < rank-2; ) {
        nextpc = pc + (pointers *= shape[i])*sizeof(char*);
        nextLevelIncrement = shape[++i]*sizeof(char*);
        for (j = 0; j < pointers; ++j)
          *((char**)pc) = nextpc, pc+=sizeof(char*), nextpc += nextLevelIncrement;
      }
      nextpc = pc + (pointers *= shape[i])*sizeof(char*);
      nextLevelIncrement = shape[++i]*itemSize;
      for (j = 0; j < pointers; ++j)
        *((char**)pc) = nextpc, pc+=sizeof(char*), nextpc += nextLevelIncrement;
      return memory;
    }
    
    #ifdef COMPILE_EXAMPLE
    
    #include<string.h>
    #include<math.h>
    
    /* XYZ chosen to mostly fit on a tall 80 character width terminal window */
    #define Z 5
    #define Y 10
    #define X 39
    
    #define BIND(A,L,H) ((L)<(A)?(A)<(H)?(A):(H):(L))
    
    void p_char(void*pv) {
      char s[3];
      int i = 0;
      s[i++] = ' ', s[i++] = *(char*)pv, s[i++] = 0;
      fputs(s, stdout);
    }
    
    void display(void*a,size_t rank,size_t*shape,void(*f)(void*)) {
      int i;
      if (0 == rank)
        (*f)(a);
      else if (1 == rank) {
        for (i = 0; i < *shape; ++i)
          (*f)(a+i);
        putchar('\n');
      } else {
        for (i = 0; i < *shape; ++i)
          display(((void**)a)[i], rank-1, shape+1, f);
        putchar('\n');
      }
    }
    
    int main() {			/* character cell 3D graphics.  Whoot */
      char***array;
      float x,y,z;
      size_t rank, shape[3], i, j, k;
      rank = 0;
      shape[rank++] = Z, shape[rank++] = Y, shape[rank++] = X;
      array = allocarray(rank, shape, sizeof(char));
      memset(**array, ' ', X*Y*Z*(sizeof(***array))); /* load the array with spaces */
      for (i = 0; i < X; ++i) {
        x = i/(float)X;
        for (j = 0; j < Y; ++j) {
          y = j/(float)X;
          z = x*y*(4*M_PI);
          z = 5.2*(0.5+(0.276765 - sin(z)*cos(z)*exp(1-z))/0.844087); /* a somewhat carefully designed silly function */
          /* printf("%g %g %g\n", x, y, z); */
          k = (int)z;
          array[BIND(k, 0, Z-1)][j][i] = '@'; /* BIND ensures a valid index  */
        }
      }
      display(array, rank, shape, p_char);
      puts("\nIt is what it is.");
      free(array);			/* one call to free */
      return EXIT_SUCCESS;
    }
    #endif
    Last edited by b49P23TIvg; May 20th, 2013 at 01:19 PM. Reason: removed vestigal "< unixdict.txt"
    [code]Code tags[/code] are essential for python code and Makefiles!

IMN logo majestic logo threadwatch logo seochat tools logo