Thread: Need help with pointer to pointer

  1. #1
    Registered User
    Join Date
    Apr 2005
    Posts
    134

    Need help with pointer to pointer

    Hello Folks,

    I have been out of touch with C for a while now. Forgettin some basics. Following code is a simulator of the part of the large code that I am planning to implement. Basically here what it is, i have an array of pointers stored in a structure. I do not know as to how many pointers I will hold this array in the begining. As the code progress I go on adding pointer to the array. I keep a count of how many pointers I added to the array in the structure itself by incrementing it everytime I add a pointer to the array.
    Now this is what I am doing (or atleast tryin) in the following code. It's working, but I am not sure if what I am seeing is correct. Can some one help me understand it.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <assert.h>
    
    int main()
    {
        int **p = NULL;
        int **top = NULL;
        char line[50];
        int arr[10];
        int i,idx;
    
        idx = 0;
    
        while (1)
        {
            printf("Enter a number to store. -1 to end: ");
            fgets(line,sizeof(line),stdin);
            sscanf(line,"%d", &i);
    
            if (i == -1)
              break;
            else
              arr[idx] = i;
    
            if (p == NULL)
            {
                p = (int **)malloc(sizeof(int *));
                (*p) = (int *)malloc(sizeof(int));
    
                assert (p != NULL && (*p) != NULL);
                printf("p = %p (*p) = %p\n",p,(*p));
                (*p) = &arr[idx];
                idx++;
                top = p;
            } else {
                p += (sizeof(int **) + sizeof(int *));
                p = (int **)malloc(sizeof(int *));
                (*p) = (int *)malloc(sizeof(int));
    
                assert (p != NULL && (*p) != NULL);
                printf("p' = %p (*p)' = %p\n",p,(*p));
                (*p) = &arr[idx];
                idx++;
            }
        }
    
        printf("Entered %d elements\n",idx);
    
        for (i=0;i< idx; i++)
        {
            printf("p'' = %p   (*p)'' = %p  arr[%d]: %d\n", top, (*top),i,*(*top));
            top = top+ (sizeof(int **) + sizeof(int *));
        }
    
        return 0;
    }
    Following is the sample output. My question is why the values of (*p)'' are different than what we are seeing in (*p) and (*p)'.

    Enter a number to store. -1 to end: 1
    p = 0x8049958 (*p) = 0x8049968
    Enter a number to store. -1 to end: 2
    p' = 0x8049978 (*p)' = 0x8049988
    Enter a number to store. -1 to end: 3
    p' = 0x8049998 (*p)' = 0x80499a8
    Enter a number to store. -1 to end: 4
    p' = 0x80499b8 (*p)' = 0x80499c8
    Enter a number to store. -1 to end: 5
    p' = 0x80499d8 (*p)' = 0x80499e8
    Enter a number to store. -1 to end: -1
    Entered 5 elements
    p'' = 0x8049958 (*p)'' = 0xbfffe7b0 arr[0]: 1
    p'' = 0x8049978 (*p)'' = 0xbfffe7b4 arr[1]: 2
    p'' = 0x8049998 (*p)'' = 0xbfffe7b8 arr[2]: 3
    p'' = 0x80499b8 (*p)'' = 0xbfffe7bc arr[3]: 4
    p'' = 0x80499d8 (*p)'' = 0xbfffe7c0 arr[4]: 5
    BTW, this is an intel PC running Linux and my compiler is gcc.

    Thanks,

  2. #2
    Registered User
    Join Date
    Sep 2001
    Posts
    752
    Code:
                (*p) = &arr[idx];
    This is the reason the value of *p is changing. Because you're reassigning it after printing it the first time.

    Code:
        for (i=0;i< idx; i++)
        {
            printf("p'' = %p   (*p)'' = %p  arr[%d]: %d\n", top, (*top),i,*(*top));
            top = top+ (sizeof(int **) + sizeof(int *));
        }
    This loop isn't really valid...
    It works for you because each of your malloc is being placed adjacent to each other on the heap. You don't technically have any gaurantee that this will happen, so this code will cause a seg-fault on many compilers (my computer crashes on this code).
    Callou collei we'll code the way
    Of prime numbers and pings!

  3. #3
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    As stated, all of your reallocation is incorrect. You have one pointer, which you point to an integer you allocate. Then you walk off the end of your pointer, into places you shouldn't, and start allocating space there. That's bad. You need something like this:
    Code:
    int **temp;
    temp = realloc( p, numofpointers * sizeof *p );
    if( temp == NULL )
    {
        ...bad things...
    }
    else
    {
        p = temp;
        ...fill in the last spot...
    }
    Quzah.
    Hope is the first step on the road to disappointment.

  4. #4
    Registered User
    Join Date
    Apr 2005
    Posts
    134
    How about this.?

    I think this is what I was intending to do.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <assert.h>
    
    int main()
    {
        int **p = NULL;
        char line[50];
        int arr[220];
        int i,idx;
    
        idx = 0;
    
        while (1)
        {
            printf("Enter a number to store. -1 to end: ");
            fgets(line,sizeof(line),stdin);
            sscanf(line,"%d", &i);
    
            if (i == -1)
              break;
            else
              arr[idx] = i;
    
            if (p == NULL)
            {
                p = (int **)malloc(sizeof(int *));
                (*p) = &arr[idx];
                assert (p != NULL && (*p) != NULL);
                printf("p = %p (*p) = %p\n",p,(*p));
                idx++;
            } else {
                p = (int **)realloc(p,sizeof(int *));
                p[idx] = &arr[idx];
                assert (&p[idx] != NULL && p[idx] != NULL);
                printf("p' = %p (*p)' = %p\n",(p+idx),*(p+idx));
                idx++;
            }
        }
    
        printf("Entered %d elements\n",idx);
    
        for (i=0;i< idx; i++)
        {
            printf("p'' = %p   (*p)'' = %p  arr[%d]: %d\n", (p+i), *(p+i),i,*(*(p+i)));
        }
    
        return 0;
    }
    I see some problem with the printf() output, 4th element I add to the array is not displayed correcty. Pointer offsets by one byte memory location. Is this a printf() related problem?

    sample Output
    Enter a number to store. -1 to end: 1
    p = 0x80499d8 (*p) = 0xbfffe670
    Enter a number to store. -1 to end: 2
    p' = 0x80499dc (*p)' = 0xbfffe674
    Enter a number to store. -1 to end: 3
    p' = 0x80499e0 (*p)' = 0xbfffe678
    Enter a number to store. -1 to end: 4
    p' = 0x80499e4 (*p)' = 0xbfffe67c
    Enter a number to store. -1 to end: 5
    p' = 0x80499e8 (*p)' = 0xbfffe680
    Enter a number to store. -1 to end: -1
    Entered 5 elements
    p'' = 0x80499d8 (*p)'' = 0xbfffe670 arr[0]: 1
    p'' = 0x80499dc (*p)'' = 0xbfffe674 arr[1]: 2
    p'' = 0x80499e0 (*p)'' = 0xbfffe678 arr[2]: 3
    p'' = 0x80499e4 (*p)'' = 0xbfffe67d arr[3]: 83886080 <------
    p'' = 0x80499e8 (*p)'' = 0xbfffe680 arr[4]: 5
    Thanks for your help

  5. #5
    {Jaxom,Imriel,Liam}'s Dad Kennedy's Avatar
    Join Date
    Aug 2006
    Location
    Alabama
    Posts
    1,065
    Quote Originally Posted by nkhambal
    Code:
                p = (int **)realloc(p,sizeof(int *));
    You'll need to change this to
    Code:
            idx++;
            p = (int **)realloc(p,sizeof(int *) * idx);
    Don't inc idx twice. Use [idx - 1] as the last element of the array.

    Also, you _could_ loose you existing array if realloc() returns NULL.

  6. #6
    Registered User
    Join Date
    Apr 2005
    Posts
    134
    Quote Originally Posted by Kennedy
    You'll need to change this to
    Code:
            idx++;
            p = (int **)realloc(p,sizeof(int *) * idx);
    Don't inc idx twice. Use [idx - 1] as the last element of the array.
    Thanks. that fixed it. Should have read the man pages for realloc before.

    Quote Originally Posted by Kennedy
    Also, you _could_ loose you existing array if realloc() returns NULL.
    This what I get from man page "If realloc() fails the original block is left untouched - it is not freed or moved.". I think I should save the pointer to original block before calling realloc()

  7. #7
    {Jaxom,Imriel,Liam}'s Dad Kennedy's Avatar
    Join Date
    Aug 2006
    Location
    Alabama
    Posts
    1,065
    Quote Originally Posted by nkhambal
    This what I get from man page "If realloc() fails the original block is left untouched - it is not freed or moved.". I think I should save the pointer to original block before calling realloc()
    Yup, the var is untouched. . . however, you are assigning it the RETURN value of realloc(), which, sometimes is NULL.

  8. #8
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by nkhambal
    This what I get from man page "If realloc() fails the original block is left untouched - it is not freed or moved.". I think I should save the pointer to original block before calling realloc()
    Hence my example, which you ignored. Also, you don't need to cast any of the *alloc functions. In C you never have to cast assignments from void pointers.


    Quzah.
    Hope is the first step on the road to disappointment.

  9. #9
    Registered User
    Join Date
    Apr 2005
    Posts
    134
    Quote Originally Posted by quzah
    Hence my example, which you ignored. Also, you don't need to cast any of the *alloc functions. In C you never have to cast assignments from void pointers.


    Quzah.
    thanks. appreciate it.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Following CTools
    By EstateMatt in forum C Programming
    Replies: 5
    Last Post: 06-26-2008, 10:10 AM
  2. Quick Pointer Question
    By gwarf420 in forum C Programming
    Replies: 15
    Last Post: 06-01-2008, 03:47 PM
  3. Parameter passing with pointer to pointer
    By notsure in forum C++ Programming
    Replies: 15
    Last Post: 08-12-2006, 07:12 AM
  4. Direct3D problem
    By cboard_member in forum Game Programming
    Replies: 10
    Last Post: 04-09-2006, 03:36 AM
  5. Struct *** initialization
    By Saravanan in forum C Programming
    Replies: 20
    Last Post: 10-09-2003, 12:04 PM