1

I know that,in const int *ptr we can change the address but cannot change the value. i.e., ptr will be stored in read-write section(stack) and the object or entity will be stored in read-only section of data segement. So, we can change the address pointing by that pointer ptr, but cannot change the object which is constant.

int main()
{
  const int *ptr=500;
  (*ptr)++;
  printf("%d\n",*ptr);
}

output is is assign the read only location to *ptr

int main()
{
  const int *ptr=500;
  ptr++;
  printf("%d\n",*ptr);
}

No compilation errors, but at runtime the output is "segmentation fault".

I agree with the first one., why I am getting an segmentation fault in 2nd one? Where exactly they will be stored?

sravanthi
  • 61
  • 1
  • 8
  • [Should be closely related](http://stackoverflow.com/a/43338131/2173917) – Sourav Ghosh Apr 21 '17 at 05:36
  • 1
    `const int *ptr=500;` is a constraint violation in Standard C. The gcc compiler behaves as if you wrote `const int *ptr = (const int *)500;` and will emit a diagnostic if you invoke the compiler in standard-compliant mode. – M.M Apr 21 '17 at 05:42
  • what do you mean by "o/p" ? – M.M Apr 21 '17 at 05:43

3 Answers3

5

The reason for the segmentation fault is different from what you think.

It is not because of const.

It is because you are not allowed to access the area that you are trying to access when doing *ptr

When you make a pointer to "something", you are still not allowed to access the data (aka dereference the pointer) until you have made the pointer point to some memory that belongs to you.

Example:

int x = 0;
int* p = (int*)500;

int a = *p;  // Invalid - p is not pointing to any memory that belongs to the program

p = &x;
int b = *p;  // Fine - p is pointing to the variable x

p++;
int c = *p;  // Invalid - p is not pointing to any memory that belongs to the program

The "invalid" code may give a segmentation fault. On the other hand, it may also just execute and produce unexpected results (or even worse: produce the expected result).

Support Ukraine
  • 42,271
  • 4
  • 38
  • 63
1
 const int *ptr=500; // WRONG

This declare a local variable which is a pointer to some constant integer. The const just tells the compiler that it is not allowed to update (overwrite) the dereferenced pointer memory cell.

However, your code is not correct; you probably want:

const int *ptr = (const int*)500;

The pointer is initialized to address 500 (you initialize the pointer).

On most systems, that address (and the following ones, e.g. at address 504 since sizeof(int) is 4) is out of the virtual address space. So dereferencing it (with *ptr) is undefined behavior and would often give some segmentation fault. See also this.

ptr will be stored in read-write section(stack) and the object or entity will be stored in read-only section of data segement.

This is wrong. Nothing is done at compilation time to keep the memory zone in a read-only text segment (however, most compilers are putting most literals or const static or global data -defined at compile-time- in it). Just you forbid the compiler to update the pointed thing (without cast).

If you need a read-only memory zone at runtime, you need to ask your OS for it (e.g. using mmap(2) & mprotect(2) on Linux). BTW protection works in pages.

On Linux, use pmap(1) (or proc(5), e.g. read sequentially the pseudo file /proc/self/maps from your program). You may want to add

char cmdbuf[64];
snprintf(cmdbuf, sizeof(cmdbuf), "pmap %d", (int) getpid());
system(cmdbuf);

before any dereference of ptr in your code to understand what is its virtual address space.

Try

cat /proc/self/maps

and

cat /proc/$$/maps

and understand their output (notice that $$ is expanded to the pid of your shell). Maybe experiment also strace(1) on your faulty program (which you should compile with gcc -Wall -g).

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • "The pointer is initialized to address 500 (you initialize the pointer)". No, pointers are not allowed to get initialized by integers in C. They may only get initialized by addresses. To get the address 500, you would have to convert the integer constant to a pointer type before initialization. – Lundin Apr 21 '17 at 06:19
1

Lots of confusion here.

and the object or entity will be stored in read-only section of data segement

No, there is no requirement for where the pointed-at object is stored. This is only determined by any qualifiers/specifiers such as const or static, when declaring the pointed-at object.

const int *ptr=500;

This is not valid C and the code must result in a compiler message. An integer cannot get assigned to a pointer, there must be a conversion in between. GCC has a known flaw here, you have to configure it to be a standard compiler. gcc -std=c11 -pedantic-errors.

If you had code such as const int *ptr=(int*)500; which is valid C, then it would set the pointer to point at address 500. If there is an int at address 500, the code will work fine. If there is no memory there that you are allowed to access, then you will get some implementation-defined behavior like a crash - memory mapping is beyond the scope of the language.

(*ptr)++;

This is not valid C and the code must result in a compiler message. You are not allowed to modify a read-only location.

Overall, your compiler seems very poorly configured. GCC, correctly configured, gives 2 compiler errors.

Lundin
  • 195,001
  • 40
  • 254
  • 396