I am writing a Unit Test that is similar to this code, and I am trying to test my values as I set them, so that I know what is going on. I don't understand why the ptr values are not being set to 1, when I run the following code. Instead when I run this it gives me an output of 10, 64, 0, 0.
Any explanation or advise would be greatly appreciated!
#include <stdio.h>
#include <stdbool.h>
typedef struct
{
bool bOne;
bool bTwo;
bool bThree;
bool bFour;
} items;
int main()
{
items item;
item.bOne = 0;
bool *ptr = &(item.bOne);
for(int i = 0; i < sizeof(items)/sizeof(bool); i++)
{
*ptr = 1;
*ptr++;
printf("ptr value = %d\n", *ptr);
}
return 0;
}
You have two major problems.
First, you have a logical error in that you advance your pointer before printing out the value it points to; instead of printing the value of the thing you just set, you're printing the value of the next uninitialized member. You need to reverse the order of the advance and print statements like so:
Or just combine the operation in one expression:
This assumes that you can use
%d
to print abool
value - I'm not sure about that offhand (may have to explicitly cast the argument to(int)
).But you have a bigger problem - it's not guaranteed that you can iterate through the members of a
struct
type with a pointer like this. Even though all the members are the same type, it's not guaranteed that there won't be padding between members (it depends on the size of thebool
type and the alignment requirements of your platform).Your code may work as intended, or it may lead to corrupted data within your
struct
instance, or any number of other issues. The safer thing to do is use a separate array of pointers to those members, since it is guaranteed that you can iterate through an array with a pointer:If you still want output, you'd write
You could get creative and combine the assignment and pointer advance within the print statement:
but that would probably get you hit.
In
*ptr++
, the++
has higher precedence than the*
, so this post-increments the pointer, and reads and discards the value originally pointed to. Now that the pointer has been incremented, you are reading uninitialized memory in theprintf
. If your intention was to increment the value being pointed at, try:Or
Edit
Hmm, since your loop bound is based upon the number of
bool
s that fit in the size of the struct, maybe your intention was to increment the pointer. In which case, you don't need to dereference it at the same time, and you shouldn't expect to get anything meaningful in theprintf
. Also, as pointed out, since the struct is not an array, you will be wandering into undefined behavior land since the compiler may decide to add padding:From C99 §6.7.2.1: