pointer segmentation fault with gcc - c

void main()
{
int *p=20;
printf("%d\n",*p);
}
This code is compiling successfully but giving segmentation fault, I am using gcc compiler.

I think you are thinking that
int *p=20;
will stroe an integer value of 20 into pointer P,But its not the case.
you are actually initializing the poinetr value to an address 20.
and in the print statement you are dereferencing it for which you might not be authorized to do.
try the below code instead
void main()
{
int a=20
int *p=&a;
printf("%d\n",*p);
}

You defined p as a pointer to memory address 20. You are then trying to dereference that address when you use the *p syntax. Address 20 is unlikely to be in the range of memory you are allowed to access, so it will give you a segmentation fault.
char* i = "abcd"; tells the compiler to set aside space for the string in memory, and point i to that place in memory. You are still assigning the place in memory to the variable.
The *i in your printf means you want the value which is pointed to by i. In your comment, you won't actually get abcd, you will actually get a. This is because i points to the first character in the string "abcd", and that character is a.
If you want an example of how you can point to integers, take a look at this code:
#include<stdlib.h>
#include<stdio.h>
int main() {
int number = 5; //A space in memory, set to the value 5
int* pointer = &number; //A pointer to point to the space in memory
printf("%d\n", *pointer); //Using * to get the value pointed to by pointer
return 0;
}

The pointer p points to the address 20 which is likely not yours. The printf call will try to print the contents of that memory, which is not allowed.

Related

Segmentation fault: but why?

#include <stdio.h>
int main()
{
int* ptr;
*ptr = 5;
printf("%d", &ptr);
return 0;
}
This was asked in a coding interview, what should be the output?
I am confused between runtime error, compilation error and segmentation fault.
Anyone who can explain why will the answer be segmentation fault?
Your code invokes undefined behavior because the pointer was left uninitialized. You need to initialize the pointer first before inserting into it anything:
int *ptr = malloc(sizeof(int) * REQ_SIZE);
After this, you will no longer get a segfault. Note that you need to put a dereference operator instead of & to print the containing value of the integer pointer.
Here's a demo.
Compilation error is an error that you face while your program is being compiled by the compiler and it's due to C grammar (Maybe you wrote an incorrect instruction grammatically.)
Runtime error is an error that you face when your program is running.
Segmentation fault is an error that you face when you're trying to access to a location in the memory that you're not allowed to access to it such as a location indicated by null pointers.
Your program has undefined behavior. Because pointers store a memory address and they cannot store a value such as a number. You could allocate some memory from heap and then you can store a value in your pointer:
int *ptr = (int*) malloc (sizeof(int));
*ptr = 5;
Or you could declare a local variable and store its address in ptr:
int value = 5;
int *ptr = &value;
Just look at the definition of Pointers. Pointer is a variable whose value is the address of another variable, i.e. direct address of the memory location. Here in your case, ptr is declared as an integer pointer, which isn't pointing to any address. That's why it gives Segmentation Fault Error. Segmentation fault is a specific kind of error caused by accessing memory that “does not belong to you". Instead of this you can do 2 things :
Assign a new integer variable's address to the pointer :
int x;
int *ptr = &x;
*ptr = 5;
Initializing the pointer using the malloc() :
int *ptr = (int*)malloc(sizeof(int) * SIZE_REQUIRED);
Also note that by using the reference of ptr in the printf() prints the address of the pointer rather than the value contained by the address it is referring to. It is demonstrated here :
printf("%d", ptr); // Prints the address of the pointer variable.
printf("%d", *ptr); // Prints the value (in this case : 5) contained by the address referenced by the pointer.

Can anyone explain to me what actually causes this Segmentation Fault and How to overcome this?

#include <stdio.h>
#define null1 ((void*)0)
#define val ((int)2)
int main() {
int *p;
p = null1;
printf("%p", &p);
//p = (int *)val;
*p = val;
//printf("\n%p", (int*)p);
return 0;
}
Output:
Segmentation fault(core dumped)
I want to assign value of macro to the Pointer.
null1 is a null pointer, its definition #define null1 ((void*)0) is one of the accepted definitions for a null pointer.
val is a macro expanding to the plain integer constant 2. Casting 2 as (int) has no effect, 2 is already an int constant value.
Storing a value to a null pointer has undefined behavior. A segmentation fault is one the possible effect of undefined behavior. A rather useful one since it allows the debugger to point to the problem immediately.
Casting any other integer value as (int *) has undefined behavior too: p = (int *)val; *p = val; is very likely to cause the same segmentation fault, but may have some other unexpected side effects, depending on the target platform specifics: if 2 happens to be the address of the self-destruct trigger port, all bets are off.
Null pointer is a special reserved value of a pointer. A pointer of any type has such a reserved value. Formally, each specific pointer type (int *, char * etc.) has its own dedicated null-pointer value. Conceptually, when a pointer has that null value it is not pointing anywhere.
Void pointer is a specific pointer type - void * - a pointer that points to some data location in storage, which doesn't have any specific type.
Here null1 refers to a void pointer whereas p is a pointer of the type integer.
Hope I was right and this is helpful to you.
Pointers directly point to memory addresses. While each program that we run is allocated a fixed memory area only (called segments). All memory address in this area is referred to using relative memory address.
But pointers have absolute memory addresses in them. Generally, the starting memory addresses are for Operating System's use. When you assign a pointer to some address outside of its segment area then it gives SIGSEGV ( Segmentation Error ).
In your case also, you are trying to assign p an address outside its segment area thus the error.
NULL pointer is an invalid pointer because it points to memory that is not valid to access so that the statment *p = val is not valid, so the Segmentation fault error appears.
To overcome this error you need to assign a valid address of a memory location to the pointer(p), such as defining a variable (var) and assign the addres to the pointer as p = &var;.
You just need to assign your pointer to your macro as code below:
#include <stdio.h>
#define val 2
int main()
{
int *p;
p = (int*)val;
printf("%p\n", &p);
printf("%d\n", p);
return 0;
}

The following C program regarding pointers is not working

#include<stdio.h>
int main(void)
{
int *pc;
*pc=100;
printf("\n Address of Pointer : %d",pc);
printf("\n Contents of Pointer : %d",*pc);
}
When I run the code in eclipse, it is saying "Pointers.exe has stopped working". What is the error?
Assigning a value to *pc is particularly dangerous. If pc contains the valid memory address , then the assignment
*pc = 100;
will attempt to modify the data stored at that address.
If the location modified by this assignment belongs to the program, it may behave erratically; if it belongs to operating system, the program will most likely crash.
Your compiler should raise a warning that pc is uninitialized.
Change it to:
int a;
int *pc;
pc = &a;
*pc = 100;
Your pc pointer was not initialized in your program.
Moreover the way your are printing a pointer value is incorrect, use this:
printf("\n Address of Pointer : %p", (void *) pc);
You forgot to point pc to somewhere useful. When you write
int *pc;
The compiler creates a pointer for you. The pointer points somewhere in memory, and you have no way of knowing where. Chances are, it points to a bad place in memory. When you overwrite it with *pc=... you overwrite a place in memory that shouldn't be overwritten.
So you need to have pc point somewhere.
int a, *pc=&a;
will do the trick. Now the compiler prepares an int for you then and you point pc to it. That way, when you write through the pointer, nothing bad will happen - you're writing on an area of memory that you know is safe.
Another way to initialize pc is like so:
int *pc = (int*)malloc(sizeof(int)); // Allocate an integer on the heap
Now *pc=100; will also work. Just don't forget to free(pc) when you're done.
You have:
int *pc;
*pc=100;
When you define the pointer to integer pc above, this pointer is not initialized, so it points to some memory that you have not allocated and you have not the right to access.
So your executable is crashing.
Just use a valid pointer, e.g. you can allocate some heap memory using malloc(sizeof(int)) (and later release it using free()), or just use stack-based memory for local automatic variables, e.g.:
/* An integer stack-allocated variable */
int n = 64;
/* Pointer to that integer */
int * pn = &n;
/* Change its value */
*pn = 100;
Moreover, to print an address, considering using the %p specifier for printf().
e.g.:
#include <stdio.h>
int main(void)
{
int n = 64;
int *pn = &n;
printf("n (before): %d\n", n);
*pn = 100;
printf("n (after): %d\n", n);
printf("Address of n: %p", (void *)pn);
return 0;
}
Output:
n (before): 64
n (after): 100
Address of n: 003AF7CC
Pointers need to POINT! A pointer is a variable that contains the adress of another variable.
int *pc;
This pointer contains some garbage value. Who knows what was in that memory before. The adress that it's pointing to could be an adress of memory that is occupied by another program. You need to assign a valid adress to a pointer if you want to change the value in that adress.
If you want to calculate sum of all the members of an array you would have to initialize the variable sum to 0 because it could contain other values.
The same is with pointers. They have to contain a valid adress of a variable if you want to modify the value.
Your program would work if you comment line *pc = 100;. You can display the adress of an uninitialized pointer but the program will crash if you try to change the value in that adress.

Why pointer is giving the same address for all array blocks?

Here is a program, I write it to output all the characters of a string one by one. But I also print the address of individual blocks of the array. The problem is addresses for all blocks are same. Why?
Does someone know?
#include<stdio.h>
int main()
{
char enter[]="Kinsman";
char *ptr;
ptr=enter;
int i=0;
while(*ptr!='\0')
{
printf("%c%p\n",*ptr,&ptr);
ptr++;
for(i=0;i<=100000000;i++);
}
return 0;
}
Because you print the address of the actual pointer.
When you use &ptr you get the address of the actual pointer and not the address if points to. Remove the ampersand (address-of operator &) so you have only ptr.
You are printing the address of the pointer, not the value of the pointer
Try
printf("%c%p\n",*ptr, static_cast<void*>(ptr));
(https://stackoverflow.com/a/18929285/259)
ptr is a pointer and it is also a variable in stack that has an address. This is fixed, while what it points to is varying by ptr++, thus you've to print the pointed-to value and not the address of the pointer itself.
printf("%c%p\n",*ptr, (void*)ptr);
// ^ remove & , and add void*

How does C interpret int in pointers and why it differ from char pointer?

#include<stdio.h>
void main()
{
int *c=12345;
printf("dec:%d hex:%x", c ,&c); // (1)
}
The line (1) prints
dec:12345 hex:8af123
where 8af123 is obviously the address which is random and machine dependent.
When I put in
printf("dec:%d", *c); // (1)
it fails, obviously.
So my question is as per theoretical concept:
*c should holds the value 12345 but it is not. why?
And in this code:
#include<stdio.h>
void main()
{
char *c='a';
printf("address store in c:%d value point by c:%c address of c:%x", c,*c ,&c); //Focus line
}
Output is:
adderess store in c:9105699 value point by c:a address of c:8af564
why it is storing 'a' in *c instead in c?
I am using gcc compiler 4.4.3.
int *c=12345;
You just made a pointer that points to the (probably) invalid address 12345.
If you pass c (no *) to printf, you're passing the pointer itself. Therefore, printf simply sees the number 12345, and prints that. It has no way of knowing that that's supposed to be a pointer.
If you pass *c, to printf, you're dereferencing the pointer – you're passing the value at memory address 12345.
Since that's not a valid address, the dereference operation will crash (to be precise, will behave undefinededly) before it ever gets to printf.
So my question is as per theoretical concept *str hold the value 12345 but it is not. why? 
int *c=12345;
is the same as:
int *c;
c=12345;
It is not the same as:
int *c;
*c=12345;
There is a semantical quirk in the C language here. The * belongs to the declaration, yet it only applies to that specific variable.
You could clarify the fact that * belongs to the declaration by putting it next to the data type:
int* c = 12345; // Don't format your declaration like this,
// see next example as to why
If you do, you will run into trouble when declaring multiple variables in the same statement:
int* a, b, c; // a is a pointer to int, b and c are plain int
// it is the same as:
int *a; int b; int c;
// and **not**
int *a; int *b; int *c;
So, you just have to learn that the * belongs to the declaration. There are no problems caused by this, because you cannot safely assign *c unless you first have assigned a valid address to c.
why it is storing 'a' in *c instead in c?
char *c='a';
printf("%d %c %x", c,*c ,&c); //Focus line
You are declaring a pointer to char that points to memory location 97 (The ascii value of a is 97).
You then try to print the pointer as a number (should print 97, but see below), the value of memory location 97 as a character (c is an invalid pointer at this stage, so the result is undefined, and the address of the pointer c (c is an aout variable located on the stack).
When I compile this code I get a
Warning: initialization makes pointer from integer without a cast
when assigning 97 to the character pointer c.
When I run this code in cygwin I get a Segmentation fault from the undefined behaviour.

Resources