0

I have assigned some random address to a pointer of a particular data type. Then I stored a value in that particular address. When I run the program, it terminates abruptly.

char *c=2000;
*c='A';
printf("%u",c);
printf("%d",*c);

I could be able to print the value of c in first printf statement. But I couldn't fetch the value stored in that address through the second one. I have executed in Cygwin GCC compiler and also in online ideone.com compiler. In ideone.com compiler it shows runtime error. What's the reason behind this?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Related Question : [Printing Pointer to Integer causes Segmentation Fault](http://stackoverflow.com/questions/19424191/printing-pointer-to-integer-causes-segmentation-fault-why/19428331#19428331) – smRaj Nov 08 '13 at 07:26

2 Answers2

2

When you assign the address 2000 to the pointer c, you are assuming that will be a valid address. Generally, though, it is not a valid address. You can't choose addresses at random and expect the compiler (and operating system) to have allocated that memory for you to use. In particular, the first page of memory (often 4 KiB, usually at least 1 KiB) is completely off limits; all attempts to read or write there are more usually indicative of bugs than intentional behaviour, and the MMU (memory management unit) is configured to reject attempts to access that memory.

If you're using an embedded microprocessor, the rules might well be different, but on a general purpose o/s like Windows with Cygwin, addresses under 0x1000 (4 KiB) are usually verboten.

You can print the address (you did it unreliably, but presumably your compiler didn't warn you; mine would have warned me about using a format for a 4-byte integer quantity to print an 8-byte address). But you can't reliably read or write the data at the address. There could be machines (usually mainframes) where simply reading an invalid address (even without accessing the memory it points at) generates a memory fault.

So, as Acme said in their answer,you've invoked undefined behaviour. You've taken the responsibility from the compiler for assigning a valid address to your pointer, but you chose an invalid value. A crash is the consequence of your bad decision.

Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
1

char *c=2000;

Assignment (and initialization) of integer values to pointers is implementation defined behavior.

Implementation-defined behavior is defined by the ISO C Standard in section 3.4.1 as:

unspecified behavior where each implementation documents how the choice is made

EXAMPLE An example of implementation-defined behavior is the propagation of the high-order bit when a signed integer is shifted right.

Any code that relies on implementation defined behaviour is only guaranteed to work under a specific platform and/or compiler. Portable programs should try to avoid such behaviour.

Community
  • 1
  • 1
Sadique
  • 22,572
  • 7
  • 65
  • 91
  • Why it is considered as undefined behaviour?..Can u please elaborate on this..?..I tried using typecast lyk char *c=(char *)2000.. But still the same prob occurs.. – Sivakumar K R Nov 08 '13 at 06:55
  • It is undefined behavior because you have no clue if that memory address is available to you or being used by another process. – Sadique Nov 08 '13 at 06:57
  • Whats the reason for abrupt termination sir..? – Sivakumar K R Nov 08 '13 at 06:59
  • The operating system may make it crash since it feels someones trying to hack into it. – Sadique Nov 08 '13 at 07:01
  • Is there any other way to assign some random address to a pointer and to overcome this undefined behavior?.. – Sivakumar K R Nov 08 '13 at 07:05
  • 1
    @SivakumarKR: No; there isn't a way to assign a random address and make it defined. You have to know what you are doing when you choose an address. Normally, you take the address of a variable, or you get a pointer from the dynamic memory allocation functions (`malloc()` et al); these will be valid. If you invent a value, it will usually be invalid. – Jonathan Leffler Nov 08 '13 at 07:07
  • This is a wrong answer. Assignment (and initialization) of integer values to pointers is **implementation defined** behavior. – Jens Gustedt Nov 08 '13 at 07:17
  • De-referencing a pointer is not undefined behavior. It would only be undefined behavior if it broke ["strict aliasing"](http://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule) or alignment. There is no telling what's there at address 2000. So the code is perfectly legal as far as the C language is concerned (but you need an explicit cast from int to pointer and the printf isn't legal). Though of course on most hosted systems with virtual addresses, that don't allow direct memory access, such code will crash & burn. That's not UB, that's a feature of a specific OS and/or CPU. – Lundin Nov 08 '13 at 07:32