C/C++ Question about pointers in C/C++

  • Thread starter Thread starter Werg22
  • Start date Start date
  • Tags Tags
    Pointers
AI Thread Summary
A pointer in C/C++ is indeed a memory address, but type compatibility is crucial. Assigning a pointer of one type to a pointer of another type without an explicit cast is illegal, as it can lead to undefined behavior. Specifically, modifying an integer through a char pointer can corrupt memory, as the compiler expects different data sizes and layouts for different types. The compiler enforces type safety to prevent such issues, but it allows casting to bypass these checks, which can lead to serious errors. Understanding these nuances is essential for safe and effective programming in C/C++.
Werg22
Messages
1,431
Reaction score
1
Isn't a pointer simply a memory address? Then why is the following illegal?

int x = 1;
char *p = &x;

&x should simply evaluate to an address in memory and that should be stored in the content of p. If this was run on a 32-bit architecture, under ASCII formatting, then

*p = 'a';

Will modify the memory unit at address &x and what would happen is that the first 8 bits of x would be modified to the bit character representation of 'a' effectively changing the value of x.

What is wrong with this reasoning?
 
Last edited:
Technology news on Phys.org
Who says it's illegal? That's perfectly reasonable c.

Will modify the byte of memory located at &x and what would happen is that the first 8 bits of x would be modified to the bit character representation of 'a' effectively changing the value of x.
It works with a single byte value in the lowest byte of the int, but it migth not give you the result you expect if you move p, especialy on a machine with little endian byte order.
 
First off, it's not legal C. You have to do an explicit cast if you want to reinterpret a pointer to one type as a pointer to another type. e.g.

char *p = (char*) &x;

Secondly, it's non-portable C; the language gives you very few guarantees about the memory layout of any type. While the most common effects of

*p = 'a'

are either to modify the least significant 8 bits or the most significant 8 bits of x as if it were stored in 2's complement notation... that is by no means a certainty. Other reasonable things that might happen are the bits change as if x is stored in 1's complement notation, or that your program soon triggers an access violation because you overwrote some 'trap' bits in the integer representation of x. And that doesn't even begin to cover the truly bizarre things that could happen!



There is almost never any reason to resort to such arcane tactics. Whenever you're tempted to do so, you should stop and take a moment to look for a more reasonable way to do what you want to do. If you decide there isn't one... then stop again and think really hard about it. If you've convinced yourself that's really what you want to do... then stop once more and really, really make sure. Only then should you do such a thing, and even then only after reconsidering it one more time.
 
attachment.php?attachmentid=16500&stc=1&d=1227233292.jpg

I draw a picture to explain you question.
Like Hurkyl said.
In a 32 bit intel CPU (which is little endian see:http://en.wikipedia.org/wiki/Little_endian)
the pointer p which is defined " char *p " is a pointer each ONE BYTE memory.
But an int variable occupy Four Bytes.

So, if you use the statement: char *p = &x; the left side and right doesn't have the same pointer type. So a implicit type convert generated by compiler.

Once you use the statement :*p = 'a'. Only one Byte in (Yellow color in my image) will be change to 'a'.
 

Attachments

  • pf_help1.jpg
    pf_help1.jpg
    6.1 KB · Views: 569
I am totally sure I have understood what you are saying zyh. You went over that point "the pointer p which is defined " char *p " is a pointer each ONE BYTE memory." too quickly. Do you mean that an int pointer points to 4 bytes, whereas a char pointer points to only 1?

If so, I'm at loss because my understanding was that &x is a single address in memory (of the first of the 4 bytes allocated to x) and through a symbolic table indicating to the compiler that x is an int type variable, the compiler 'knows' it needs to write on that address and the 3 following when changing the value of x.

What loses me is that I don't understand why, say x is an int and ch a char, &ch and &x are fundamentally different. According to my schema, they both evaluate to memory addresses, don't they?
 
Do you mean that an int pointer points to 4 bytes, whereas a char pointer points to only 1?
The pointers are the same as far as the processor is concerned, the compiler has to keep track of the differences.
the compiler 'knows' it needs to write on that address and the 3 following when changing the value of x.
Yes
say x is an int and ch a char, &ch and &x are fundamentally different. According to my schema, they both evaluate to memory addresses, don't they?
Yes - that's the problem with c. You could reserve some memory for a single char and then through a pointer write a 4byte int starting at that address. the compiler will happily overwrite any data/program memory after the char.
 
Last edited:
So is it only through information that the compiler keeps in the symbolic table that it is capable to distinguish between pointers and enforce assignment rules? In that case, does this mean we can't operate with pointers that don't originate from declared variables, i.e. in the same way int x = 3; is different from int y = 3, x = y;, because then the compiler has no means to enforce rules?
 
You can do pretty much anythign you want with pointers.
There is nothing to stop you doing
char p; memset(*p,0,1024);
which will overwrite the next k of memory.

The compiler does it's best to protect you by forcing you to cast the wrong type of pointer.
int x = 1; char *p = &x; //The compiler will warn you (or give an error on some compilers)
int x = 1; char *p = (char*)&x; //Tells the compiler you think you know what you are doing.
Generally at run time the OS doesn't know what the pointer points at.
void *p explicitly says you don't care what it is going to point at - so you can write a function that can work with different types.
 
I see. Now, there aren't really any 'type' of pointers, it's all about the compiler checking the statements involving pointers against their original declaration, right? Do we only think of them in this way so that we can predict how the compiler will react?

But then again there aren't really any types since it's all 1's and 0's in the end, the compiler is responsible to 'fake' the difference.
 
  • #10
Werg22 said:
I see. Now, there aren't really any 'type' of pointers, it's all about the compiler checking the statements involving pointers against their original declaration, right? Do we only think of them in this way so that we can predict how the compiler will react?
No, we think about it this way because its simpler, harder to make mistakes, and gives the compiler opportunities for optimization that it wouldn't otherwise have.
 
  • #11
mgb_phys said:
The pointers are the same as far as the processor is concerned, the compiler has to keep track of the differences.

Or to put it another way: &ch and &x are not fundamentally different. It is just that the compiler pretends they are different, as a safety feature. This is because even though the compiler knows how to interchange char * and int * as if they were the same type, it is almost always a bad idea to do this (for the reasons described by Hurkyl and others). When you cast a char * to an int * you are not actually changing its value, you are just circumventing the safety feature.
 

Similar threads

Back
Top