strange pointer behavior

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Bruno van Dooren

    #1

    strange pointer behavior

    Hi All,

    i have some (3) different weird pointer problems that have me stumped. i
    suspect that the compiler behavior is correct because gcc shows the same
    results.

    ----------------------------------------------
    //example 1:
    typedef int t_Array[10];
    int main(int argc, char* argv[])
    {
    t_Array array;
    array[0] = 123;
    array[9] = 321;

    t_Array *ptrArray[] = {&array};
    t_Array *element = ptrArray[0];

    printf("array = 0x%08x, ptrArray[0] = 0x%08x, element = 0x%08x, *element =
    0x%08x\n",
    array, ptrArray[0], element, *element);

    printf("array[9] = %d, (*element)[9] = %d, element[9] = %d\n",
    array[9], (*element)[9], element[9]);

    return 0;
    }

    now according to the print statements, the different pointers all point to
    the same thing, even though 'element' is dereferenced at one place, and not
    dereferenced at another place. if i try to print a value from the array, i
    get 2 different results.
    ??
    ----------------------------------------------
    example 2:
    typedef int t_Array[10];
    void function(t_Arra y Array)
    {
    t_Array *ptrArray[] = {&Array}; //error
    }
    int main(int argc, char* argv[])
    {
    t_Array array;
    t_Array *ptrArray[] = {&array}; //no error
    return 0;
    }
    the 2 declarations of the arrays look the same to me, but 1 gives an error,
    and the other one doesn't. i have looked up the documentation of that
    error, but that didn't shine much light.
    ??

    ----------------------------------------------
    example 3:
    typedef int t_Array[10];
    void function(t_Arra y Array)
    {
    t_Array *element = NULL;
    void * ptrArray[] = {NULL};

    ptrArray[0] = &Array; //first element should be pointer to a t_Array
    element = (t_Array *)ptrArray[0];
    printf("Weird Failure: (*element)[9] = %d\n", (*element)[9]);

    ptrArray[0] = Array; //first element should be Array itself
    element = (t_Array *)ptrArray[0];
    printf("Weird Success: (*element)[9] = %d\n", (*element)[9]);
    }
    int main(int argc, char* argv[])
    {
    t_Array array;
    array[9] = 321;
    function(array) ;
    return 0;
    }
    this is what really caused my headaches. i used void pointers to get rid of
    the error, but that caused weird behavior. in the first situation in
    'function', i expect to dereference a pointer to end up with an array, but
    that clearly is not what happens.
    in the second situation i expect to do something illegal: ie to use a
    pointer to an array as the array itself, and somehow that seems to work.
    what do i miss here?

    i would be very grateful for some light on this murky behavior (or at least
    my murky understanding).

    kind regards,
    Bruno.


  • Michael Mair

    #2
    Re: strange pointer behavior

    Bruno van Dooren wrote:[color=blue]
    > Hi All,
    >
    > i have some (3) different weird pointer problems that have me stumped. i
    > suspect that the compiler behavior is correct because gcc shows the same
    > results.
    >
    > ----------------------------------------------
    > //example 1:[/color]

    You forgot to #include <stdio.h>
    [color=blue]
    > typedef int t_Array[10];
    > int main(int argc, char* argv[])
    > {
    > t_Array array;
    > array[0] = 123;
    > array[9] = 321;
    >
    > t_Array *ptrArray[] = {&array};
    > t_Array *element = ptrArray[0];
    >
    > printf("array = 0x%08x, ptrArray[0] = 0x%08x, element = 0x%08x, *element =
    > 0x%08x\n",[/color]

    Why do you not use %p which works on all platforms instead of %x which
    potentially invokes undefined behaviour?
    [color=blue]
    > array, ptrArray[0], element, *element);[/color]

    Note that you have a function with variable argument list: If you
    want a specific pointer type (here: void*), cast.
    [color=blue]
    >
    > printf("array[9] = %d, (*element)[9] = %d, element[9] = %d\n",
    > array[9], (*element)[9], element[9]);[/color]

    Note: element[9] is a pointer and points to storage you do not
    own. Bang.[color=blue]
    >
    > return 0;
    > }
    >
    > now according to the print statements, the different pointers all point to
    > the same thing, even though 'element' is dereferenced at one place, and not
    > dereferenced at another place. if i try to print a value from the array, i
    > get 2 different results.
    > ??[/color]

    For reference:

    #include <stdio.h>

    typedef int t_Array[10];

    int main (void)
    {
    t_Array array;
    array[0] = 123;
    array[9] = 321;

    t_Array *ptrArray[] = {&array};
    t_Array *element = ptrArray[0];

    printf("array = %10p, ptrArray[0] = %10p, element = %10p, "
    "*element = %10p\n", (void *)array, (void *)ptrArray[0],
    (void *)element, (void *)*element);

    printf("array[9] = %d, (*element)[9] = %d, element[9] = %p\n",
    array[9], (*element)[9], (void *)element[9]);

    return 0;
    }


    ptrArray[0] aka element is a t_Array* containing &array.
    The array starts at the same storage location as array[0],
    so ptrArray[0][0] aka element[0] aka *element aka array
    is the same.
    array[9] and (*element)[9] are the same.
    element[9] is the same as *(element+9) is
    *(t_Array *)((unsigned char*)element + 9*sizeof *element) is
    a t_Array starting at the location
    ((unsigned char*)&array + 9*sizeof array) which certainly is
    not an int value and certainly not within the memory you own.

    [color=blue]
    > ----------------------------------------------
    > example 2:
    > typedef int t_Array[10];
    > void function(t_Arra y Array)
    > {
    > t_Array *ptrArray[] = {&Array}; //error
    > }
    > int main(int argc, char* argv[])
    > {
    > t_Array array;
    > t_Array *ptrArray[] = {&array}; //no error
    > return 0;
    > }
    > the 2 declarations of the arrays look the same to me, but 1 gives an error,
    > and the other one doesn't. i have looked up the documentation of that
    > error, but that didn't shine much light.
    > ??
    >
    > ----------------------------------------------
    > example 3:
    > typedef int t_Array[10];
    > void function(t_Arra y Array)
    > {
    > t_Array *element = NULL;
    > void * ptrArray[] = {NULL};
    >
    > ptrArray[0] = &Array; //first element should be pointer to a t_Array
    > element = (t_Array *)ptrArray[0];
    > printf("Weird Failure: (*element)[9] = %d\n", (*element)[9]);
    >
    > ptrArray[0] = Array; //first element should be Array itself
    > element = (t_Array *)ptrArray[0];
    > printf("Weird Success: (*element)[9] = %d\n", (*element)[9]);
    > }
    > int main(int argc, char* argv[])
    > {
    > t_Array array;
    > array[9] = 321;
    > function(array) ;
    > return 0;
    > }
    > this is what really caused my headaches. i used void pointers to get rid of
    > the error, but that caused weird behavior. in the first situation in
    > 'function', i expect to dereference a pointer to end up with an array, but
    > that clearly is not what happens.
    > in the second situation i expect to do something illegal: ie to use a
    > pointer to an array as the array itself, and somehow that seems to work.
    > what do i miss here?
    >
    > i would be very grateful for some light on this murky behavior (or at least
    > my murky understanding).[/color]

    Your problem with examples 1, 2 and 3 is that you
    a) do not understand fully the difference between pointer and array.
    See the comp.lang.c FAQ to help further your understanding.
    Your problem with examples 2 and 3 is that you seem unaware of
    the fact that
    b) you cannot pass arrays to functions -- instead you always pass
    pointers to the first array element.
    c) typedefs are just a way to write types conveniently or create
    some abstraction by logical markup (naming a type's role instead of
    its physical type) but not a way to generate new types.

    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.

    Comment

    • Bruno van Dooren

      #3
      Re: strange pointer behavior

      [color=blue]
      >
      > Why do you not use %p which works on all platforms instead of %x which
      > potentially invokes undefined behaviour?[/color]
      i didn't know that one. thanks.

      i also think i get the rest of your explanation. thanks for your reply.

      kind regards,
      Bruno.




      [color=blue]
      >[color=green]
      >> array, ptrArray[0], element, *element);[/color]
      >
      > Note that you have a function with variable argument list: If you
      > want a specific pointer type (here: void*), cast.
      >[color=green]
      >>
      >> printf("array[9] = %d, (*element)[9] = %d, element[9] = %d\n",
      >> array[9], (*element)[9], element[9]);[/color]
      >
      > Note: element[9] is a pointer and points to storage you do not
      > own. Bang.[color=green]
      >>
      >> return 0;
      >> }
      >>
      >> now according to the print statements, the different pointers all point
      >> to
      >> the same thing, even though 'element' is dereferenced at one place, and
      >> not
      >> dereferenced at another place. if i try to print a value from the array,
      >> i
      >> get 2 different results.
      >> ??[/color]
      >
      > For reference:
      >
      > #include <stdio.h>
      >
      > typedef int t_Array[10];
      >
      > int main (void)
      > {
      > t_Array array;
      > array[0] = 123;
      > array[9] = 321;
      >
      > t_Array *ptrArray[] = {&array};
      > t_Array *element = ptrArray[0];
      >
      > printf("array = %10p, ptrArray[0] = %10p, element = %10p, "
      > "*element = %10p\n", (void *)array, (void *)ptrArray[0],
      > (void *)element, (void *)*element);
      >
      > printf("array[9] = %d, (*element)[9] = %d, element[9] = %p\n",
      > array[9], (*element)[9], (void *)element[9]);
      >
      > return 0;
      > }
      >
      >
      > ptrArray[0] aka element is a t_Array* containing &array.
      > The array starts at the same storage location as array[0],
      > so ptrArray[0][0] aka element[0] aka *element aka array
      > is the same.
      > array[9] and (*element)[9] are the same.
      > element[9] is the same as *(element+9) is
      > *(t_Array *)((unsigned char*)element + 9*sizeof *element) is
      > a t_Array starting at the location
      > ((unsigned char*)&array + 9*sizeof array) which certainly is
      > not an int value and certainly not within the memory you own.
      >
      >[color=green]
      >> ----------------------------------------------
      >> example 2:
      >> typedef int t_Array[10];
      >> void function(t_Arra y Array)
      >> {
      >> t_Array *ptrArray[] = {&Array}; //error
      >> }
      >> int main(int argc, char* argv[])
      >> {
      >> t_Array array;
      >> t_Array *ptrArray[] = {&array}; //no error
      >> return 0;
      >> }
      >> the 2 declarations of the arrays look the same to me, but 1 gives an
      >> error, and the other one doesn't. i have looked up the documentation of
      >> that
      >> error, but that didn't shine much light.
      >> ??
      >>
      >> ----------------------------------------------
      >> example 3:
      >> typedef int t_Array[10];
      >> void function(t_Arra y Array)
      >> {
      >> t_Array *element = NULL;
      >> void * ptrArray[] = {NULL};
      >>
      >> ptrArray[0] = &Array; //first element should be pointer to a t_Array
      >> element = (t_Array *)ptrArray[0];
      >> printf("Weird Failure: (*element)[9] = %d\n", (*element)[9]);
      >>
      >> ptrArray[0] = Array; //first element should be Array itself
      >> element = (t_Array *)ptrArray[0];
      >> printf("Weird Success: (*element)[9] = %d\n", (*element)[9]);
      >> }
      >> int main(int argc, char* argv[])
      >> {
      >> t_Array array;
      >> array[9] = 321;
      >> function(array) ;
      >> return 0;
      >> }
      >> this is what really caused my headaches. i used void pointers to get rid
      >> of
      >> the error, but that caused weird behavior. in the first situation in
      >> 'function', i expect to dereference a pointer to end up with an array,
      >> but
      >> that clearly is not what happens.
      >> in the second situation i expect to do something illegal: ie to use a
      >> pointer to an array as the array itself, and somehow that seems to work.
      >> what do i miss here?
      >>
      >> i would be very grateful for some light on this murky behavior (or at
      >> least
      >> my murky understanding).[/color]
      >
      > Your problem with examples 1, 2 and 3 is that you
      > a) do not understand fully the difference between pointer and array.
      > See the comp.lang.c FAQ to help further your understanding.
      > Your problem with examples 2 and 3 is that you seem unaware of
      > the fact that
      > b) you cannot pass arrays to functions -- instead you always pass
      > pointers to the first array element.
      > c) typedefs are just a way to write types conveniently or create
      > some abstraction by logical markup (naming a type's role instead of
      > its physical type) but not a way to generate new types.
      >
      > Cheers
      > Michael
      > --
      > E-Mail: Mine is an /at/ gmx /dot/ de address.[/color]


      Comment

      Working...