strange pointer problem, now ansi example

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

Victor Bazarov

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

't_Array' is a synonym for an array of 10 ints.
int main(int argc, char* argv[])
{
t_Array array;

'array' is an array of 10 ints.
array[0] = 123;
array[9] = 321;

The rest is left uninitialised.
t_Array *ptrArray[] = {&array};

'ptrArray' is an array of (1) pointers to arrays of 10 ints.
t_Array *element = ptrArray[0];

'element' is a pointer to an array of 10 ints, initialised from the first
element of 'ptrArray' array.
printf("array = 0x%08x, ptrArray[0] = 0x%08x, element = 0x%08x, *element =
0x%08x\n",
array, ptrArray[0], element, *element);

Here you print the address of the first element of the 'array' (a pointer
to an int), then the address of the 'array' array (a pointer to an array
of 10 ints), then the same thing (as 'element' since you initialised it to
the same value as 'ptrArray[0]'), then the address of the first element of
the array to which 'element' points (IOW, the address of the first element
of 'array' array). They are all the same location in memory.
printf("array[9] = %d, (*element)[9] = %d, element[9] = %d\n",
array[9], (*element)[9], element[9]);

Here 'array[9]' is an int. (*element)[9] is another int (the same as
'array[9]'), and 'element[9]' is the _tenth_array_of_10_ints_sitting_in_
_memory_counting_from_'array'_, which *doesn't exist* since 'array' is
the only array there is. This statement has undefined behaviour because
you're dereferencing an invalid pointer ('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.

Only 2 different results?

'Array' is passed by value? Most likely it decays to a pointer to 'int'
here since arrays cannot be passed by value.
{
t_Array *ptrArray[] = {&Array}; //error

Of course. You're trying to initialise a pointer to an array from the
address of a pointer. Different types.

To learn what your 'Array' here is, use <typeinfo> and do

printf("The type of 'Array' is (%s)\n", typeid(Array).name());
}
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.
??

Do a bit of experimenting before asking:
-----
// example 2:
#include <stdio.h>
#include <typeinfo>

typedef int t_Array[10];
void function(t_Array Array)
{
printf("%s\n", typeid(Array).name());
// t_Array *ptrArray[] = {&Array}; //error
}
int main(int argc, char* argv[])
{
t_Array array;
t_Array *ptrArray[] = {&array}; //no error
function(array);
return 0;
}
-----
Again 'Array' is a pointer to int.
{
t_Array *element = NULL;
void * ptrArray[] = {NULL};

ptrArray[0] = &Array; //first element should be pointer to a t_Array

The first element is a pointer to 'void'. Why should it be anything but?
element = (t_Array *)ptrArray[0];

Now you're invoking undefined behaviour because to begin with, 'Array' is
not a pointer to a t_Array.
printf("Weird Failure: (*element)[9] = %d\n", (*element)[9]);

Of course it's weird. What else should undefined behaviour be?
ptrArray[0] = Array; //first element should be Array itself
element = (t_Array *)ptrArray[0];
printf("Weird Success: (*element)[9] = %d\n", (*element)[9]);

There is no success or failure here. The behaviour is still undefined.
}
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.

Yes. Arrays in C++ are rather strange things. They are prone to decay.
The main reason for your troubles is that you don't take the decay into
consideration.
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).

Ask more questions after you read my answers.

V
 
B

Bruno van Dooren

i will post my questions tomorrow after i have had time to read your reply
thouroughly. it is now 22:30 (Belgium) and i think this is a good time to
close my laptop and go to bed :).

thanks in advance.
Bruno.

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

't_Array' is a synonym for an array of 10 ints.
int main(int argc, char* argv[])
{
t_Array array;

'array' is an array of 10 ints.
array[0] = 123;
array[9] = 321;

The rest is left uninitialised.
t_Array *ptrArray[] = {&array};

'ptrArray' is an array of (1) pointers to arrays of 10 ints.
t_Array *element = ptrArray[0];

'element' is a pointer to an array of 10 ints, initialised from the first
element of 'ptrArray' array.
printf("array = 0x%08x, ptrArray[0] = 0x%08x, element = 0x%08x,
*element =
0x%08x\n",
array, ptrArray[0], element, *element);

Here you print the address of the first element of the 'array' (a pointer
to an int), then the address of the 'array' array (a pointer to an array
of 10 ints), then the same thing (as 'element' since you initialised it to
the same value as 'ptrArray[0]'), then the address of the first element of
the array to which 'element' points (IOW, the address of the first element
of 'array' array). They are all the same location in memory.
printf("array[9] = %d, (*element)[9] = %d, element[9] = %d\n",
array[9], (*element)[9], element[9]);

Here 'array[9]' is an int. (*element)[9] is another int (the same as
'array[9]'), and 'element[9]' is the _tenth_array_of_10_ints_sitting_in_
_memory_counting_from_'array'_, which *doesn't exist* since 'array' is
the only array there is. This statement has undefined behaviour because
you're dereferencing an invalid pointer ('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.

Only 2 different results?

'Array' is passed by value? Most likely it decays to a pointer to 'int'
here since arrays cannot be passed by value.
{
t_Array *ptrArray[] = {&Array}; //error

Of course. You're trying to initialise a pointer to an array from the
address of a pointer. Different types.

To learn what your 'Array' here is, use <typeinfo> and do

printf("The type of 'Array' is (%s)\n", typeid(Array).name());
}
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.
??

Do a bit of experimenting before asking:
-----
// example 2:
#include <stdio.h>
#include <typeinfo>

typedef int t_Array[10];
void function(t_Array Array)
{
printf("%s\n", typeid(Array).name());
// t_Array *ptrArray[] = {&Array}; //error
}
int main(int argc, char* argv[])
{
t_Array array;
t_Array *ptrArray[] = {&array}; //no error
function(array);
return 0;
}
-----
Again 'Array' is a pointer to int.
{
t_Array *element = NULL;
void * ptrArray[] = {NULL};

ptrArray[0] = &Array; //first element should be pointer to a t_Array

The first element is a pointer to 'void'. Why should it be anything but?
element = (t_Array *)ptrArray[0];

Now you're invoking undefined behaviour because to begin with, 'Array' is
not a pointer to a t_Array.
printf("Weird Failure: (*element)[9] = %d\n", (*element)[9]);

Of course it's weird. What else should undefined behaviour be?
ptrArray[0] = Array; //first element should be Array itself
element = (t_Array *)ptrArray[0];
printf("Weird Success: (*element)[9] = %d\n", (*element)[9]);

There is no success or failure here. The behaviour is still undefined.
}
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.

Yes. Arrays in C++ are rather strange things. They are prone to decay.
The main reason for your troubles is that you don't take the decay into
consideration.
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).

Ask more questions after you read my answers.

V
 
B

Bruno van Dooren

----------------------------------------------
//example 1:
typedef int t_Array[10];

't_Array' is a synonym for an array of 10 ints.
int main(int argc, char* argv[])
{
t_Array array;

'array' is an array of 10 ints.
array[0] = 123;
array[9] = 321;

The rest is left uninitialised.
t_Array *ptrArray[] = {&array};

'ptrArray' is an array of (1) pointers to arrays of 10 ints.
t_Array *element = ptrArray[0];

'element' is a pointer to an array of 10 ints, initialised from the first
element of 'ptrArray' array.
printf("array = 0x%08x, ptrArray[0] = 0x%08x, element = 0x%08x,
*element =
0x%08x\n",
array, ptrArray[0], element, *element);

Here you print the address of the first element of the 'array' (a pointer
to an int), then the address of the 'array' array (a pointer to an array
of 10 ints), then the same thing (as 'element' since you initialised it to
the same value as 'ptrArray[0]'), then the address of the first element of
the array to which 'element' points (IOW, the address of the first element
of 'array' array). They are all the same location in memory.
if i understand you correctly, element is a pointer to the first value, and
(*element) is a pointer to the first value. how can that be? the
dereferencing doesn't seem to make a difference.


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

Here 'array[9]' is an int. (*element)[9] is another int (the same as
'array[9]'), and 'element[9]' is the _tenth_array_of_10_ints_sitting_in_
_memory_counting_from_'array'_, which *doesn't exist* since 'array' is
the only array there is. This statement has undefined behaviour because
you're dereferencing an invalid pointer ('element[9]').
but the previous print statement showed that element and *element are the
same. if so, then they are both pointers to the first element in the array.
in that case, the [] operator should have the same behavior?
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.

Only 2 different results?

'Array' is passed by value? Most likely it decays to a pointer to 'int'
here since arrays cannot be passed by value.
{
t_Array *ptrArray[] = {&Array}; //error

Of course. You're trying to initialise a pointer to an array from the
address of a pointer. Different types.
so they are different because Array is now a real pointer, located on the
stack somewhere, and not the array itself?
To learn what your 'Array' here is, use <typeinfo> and do

printf("The type of 'Array' is (%s)\n", typeid(Array).name());
}
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.
??

Do a bit of experimenting before asking:
the explanation is the same as your previous one (i think): in the no error
case, the array is a real array, while in the subroutine it has decayed to a
real pointer.
\
-----
// example 2:
#include <stdio.h>
#include <typeinfo>

typedef int t_Array[10];
void function(t_Array Array)
{
printf("%s\n", typeid(Array).name());
// t_Array *ptrArray[] = {&Array}; //error
}
int main(int argc, char* argv[])
{
t_Array array;
t_Array *ptrArray[] = {&array}; //no error
function(array);
return 0;
}
-----
Again 'Array' is a pointer to int.
{
t_Array *element = NULL;
void * ptrArray[] = {NULL};

ptrArray[0] = &Array; //first element should be pointer to a t_Array

The first element is a pointer to 'void'. Why should it be anything but?
its type is void, but what it points to is the array. my mistake here is
that i assumed that it would be a pointer to a pointer, instead of a pointer
to the first element.
element = (t_Array *)ptrArray[0];

Now you're invoking undefined behaviour because to begin with, 'Array' is
not a pointer to a t_Array.
indeed. i thought i had a pointer to a pointer, but instead i have a pointer
to the first element.
printf("Weird Failure: (*element)[9] = %d\n", (*element)[9]);

Of course it's weird. What else should undefined behaviour be?
in that case this should fail, since my assumption was not valid.. it seems
as if i am dereferencing whatever value is in the first element.

ptrArray[0] = Array; //first element should be Array itself
element = (t_Array *)ptrArray[0];
printf("Weird Success: (*element)[9] = %d\n", (*element)[9]);

There is no success or failure here. The behaviour is still undefined.
the reason that this works is that (probably) the value of the pointer is
copied into the first element of prtArray, so dereferencing that value would
give me the address again, on which i could then (legally) use the []
operator on it to end up with a value in my original array.
}
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.

Yes. Arrays in C++ are rather strange things. They are prone to decay.
The main reason for your troubles is that you don't take the decay into
consideration.
indeed.
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).

Ask more questions after you read my answers.
i think that i understan now (or at least know what i did wrong)
the main reason for my confusion stems from using the typedef. that led me
to believe that &array would give me a pointer to a pointer, instead of a
pointer to the first value.

i still don't understand though why (in my first example) element and
*element have the same value, yet using the [] operator on them gives
different results.

thanks for your reply.

kind regards,
Bruno.
 

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,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top