Initializing a pointer gives a segmentation error

I wrote a C program as follows:

CASE 1

int *a; /* pointer variable declaration */ int b; /* actual variable declaration */ *a=11; a=&b;/* store address of b in pointer variable*/ 

It gives a segmentation error when the program starts.

I changed the code as follows:

CASE 2

 int *a; /* pointer variable declaration */ int b; /* actual variable declaration */ a=&b;/* store address of b in pointer variable*/ *a=11; 

Now it works fine.

If anyone knows, explain why he is giving a segmentation error in CASE 1.

+4
source share
5 answers
 CASE .1 int *a; /* pointer variable declaration */ int b; /* actual variable declaration */ *a=11;//Not valid means you are not owner of the address where a now pointing it is unknown and accessing this will segfault/ a=&b;/* store address of b in pointer variable*/ 

This will be a segmentation error, because the address you use is not a valid address and you store 11 there, which is illegal.

  b +-------+ +--------+ | + | 11 | |Unknown| | | +---+---+ +---+----+ | | | | + + aa CASE .2 int *a; /* pointer variable declaration */ int b; /* actual variable declaration */ a=&b;/* store address of b in pointer variable*/ *a=11; 

Now it works fine, because address b is valid, there you save 11, which is legal.

Also above are cases of incorrect way of declaring a pointer

  int *a = NUll; a = malloc(sizeof(int)); *a=5; free(a);//must 

or

  int *a = NUll; int b; a = &b; *a=5; 

This will eliminate the segmentation error many times, which is hard to find.

+15
source
 int *a; // a pointer variable that can hold a memory address of a integer value. 

In case 1,

  *a = 10; // here you have asigned 10 to unknown memory address; 

It shows a segmentation error due to the assignment of a value to a memory address that is not defined. Undefined.

In case 2,

 a=&b; // assigning a proper memory address to a. *a=11;// assigning value to that address 

Consider the following example:

 #include<stdio.h> int main() { int *a,b=10; printf("\n%d",b); a=&b; *a=100; printf("-->%d",b); } Output: 10-->100 

Here's how it works.

  b // name ---------- + 10 + // value ---------- 4000 // address 

The memory memory b is 4000.

 a=&b => a=4000; *a=100 => *(4000)=100 => valueat(4000) => 100 

After manipulation, it looks like this.

  b // name ---------- + 100 + // value ---------- 4000 // address 
+4
source

One line: in the first code, you are playing an uninitialized pointer that demonstrates undefined behavior, and in the second code, you are looking for an initialized pointer that will give access to the value at the address.

A little explanation:

First you need to understand that a pointer is nothing more than an integer, but with *var we tell the compiler that we will use the contents of the var variable (the integer in it) as the address for select the value in this address. If **var exists, then we tell the compiler that we will first use the stored value of the var variable to retrieve the value at the address and again use this extracted value as the address and get the value stored in it.

So in your first ad this is:

  +----------+ +----------+ | garbage | | garbage | +----------+ +----------+ | a | | b | +----------+ +----------+ | addr1 | | addr2 | +----------+ +----------+ 

Then you try to use the value stored in a as the address. a contains garbage, it can be any value, but you do not have access to any address. Therefore, the next moment when you execute *a , it will use the stored value in a as the address. Since a stored value can be anything, anything can happen.

If you have permission to access the location, the code will continue to run without segmentation failures. If the address is an address from the heap storage structure or another area of ​​memory that your code allocates from the heap or stack, then when you execute *a = 10 , it will simply destroy the existing value with 10 at this location, This can lead to undefined behavior , because now you have changed something, not knowing the context that has the actual power of memory. If you do not have memory rights, you simply get a segmentation error. This is called dereferencing an uninitialized pointer.

The next statement that you execute a = &b , which simply assigns the address b to a . This does not help, as the previous line dereferences the uninitialized pointer.

In the following code, you have something similar after the third statement:

  +----------+ +----------+ | addr2 |---+ | garbage | +----------+ | +----------+ | a | +--> | b | +----------+ +----------+ | addr1 | | addr2 | +----------+ +----------+ 

The third statement assigns address b to a . Prior to this, a not dereferenced, so the garbage value stored in a before initialization is never used as an address. Now that you assign the actual address of your knowledge to a , dereferencing a will now give you access to the value pointed to by a .

Expanding the answer, you need to make sure that even if you assign a valid address to the pointer, you must make sure that the pointer that the pointer points to does not expire during the dereferencing of the pointer. For example, a returning local variable.

 int foo (void) { int a = 50; return &a; //Address is valid }//After this `a' is destroyed (lifetime finishes), accessing this address //results in undefined behaviour int main (void) { int *v = foo (); *v = 50; //Incorrect, contents of `v' has expired lifetime. return 0; } 

The same is the case when accessing a free memory cell from the heap.

 int main (void) { char *a = malloc (1); *a = 'A'; //Works fine, because we have allocated memory free (a); //Freeing allocated memory *a = 'B'; //Undefined behaviour, we have already freed //memory, it not for us now. return 0; } 
+4
source

In the first case, you indicated a pointer, but you did not specify the address to which it should point, so the pointer would contain an address that belonged to another process in the system (or it would contain an undesirable value that was not an address at all, or it would contain zero, which cannot be a memory address), so the operating system sends a signal to prevent the memory from working incorrectly, and therefore a segmentation error occurs.

In the second case, you assign an address to a variable that should be updated to a pointer, and save the value, which is the correct way, and therefore there is no segmentation error.

+2
source

int a stores a random integer value. Therefore, by saying, by saying * a, you can access a memory location that is out of scope or is invalid. So this is a seg error.

+1
source

Source: https://habr.com/ru/post/1493580/


All Articles