strange pointer behavior

B

Bruno van Dooren

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_Array 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_Array 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.
 
M

Michael Mair

Bruno said:
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.

You forgot to #include said:
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",

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

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

Note: element[9] is a pointer and points to storage you do not
own. Bang.
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.
??

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.

----------------------------------------------
example 2:
typedef int t_Array[10];
void function(t_Array 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_Array 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).

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
 
B

Bruno van Dooren

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

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

kind regards,
Bruno.




array, ptrArray[0], element, *element);

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

Note: element[9] is a pointer and points to storage you do not
own. Bang.
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.
??

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.

----------------------------------------------
example 2:
typedef int t_Array[10];
void function(t_Array 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_Array 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).

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top