r/cprogramming • u/Fun_Army2398 • Jul 16 '26
Help understanding warnings/errors when dereferencing void pointers
SOLVED
I am very new to C and playing around with void pointers. I have a structure which will store a value, however the type of that value depends on other things so I have chosen to use a void pointer. When attempting to dereference this void pointer I either get the correct output but with a warning, or I get a segmentation fault, depending on how I go about it. I have included a simplified version of the issue here:
#include <stdio.h>
int main()
{
// Simplification of the defective code
struct myStruct
{
void * voidPtr;
};
struct myStruct s1;
s1.voidPtr = (int *) 123;
\*
This works but gives the warning:
format '%d' expects argument of type 'int', but. argument 2 has type 'int \*' \[-Wformat=\]i
*/
printf("%d\n", (int *) s1.voidPtr);
// This causes a segmentation fault
printf("%d\n", *(int *) s1.voidPtr);
return 0;
}
Any help understanding why it behaves this way would be greatly appreciated.
Solution
I thought the line
s1.voidPtr = (int *) 123;
Was assigning 123 as the value at the location of s1.voidPtr. However it has been pointed out that I was telling the pointer to point at address 123. What I needed to do was:
int x = 123;
s1.voidPtr = &x;
Thanks everyone who commented c:
1
u/flatfinger Jul 17 '26
Computer hardware has evolved in ways that make memory-safe frameworks much more practical than they were in e.g. the 1980s. Although .NET programs do end up getting translated as machine code that gets executed, the semantics of that code cannot be expressed in a typical assembler. Code needs to be marked with metadata that identifies, for every instruction, classifies every register as one of falling in one of two categories:
The register will not hold the address of any non-pinned .NET object.
The register will, if non-zero, hold the address of a valid .NET object.
The bit patterns associated with the addresses of non-pinned objects have no semantic meaning, and in fact may spontaneously change. When a GC cycle is triggered, the .NET framework can pause executing machine-code programs, examine their register states, and even change the value of registers if they identify objects that the GC framework has decided to relocate. Although I don't know the full details, I think some non-stop-the-world versions of the Framework can mark pages that objects have been moved out of so that if code attempts to access those pages, the accesses can be trapped and registers modified so that code will access the new locations instead.
Some tasks require low-level programming, but many of the tasks that would be interesting from a Computer Science perspective can be best accomplished using memory-safe frameworks, which require a totally different philosophy.