C memory management for variables

I am new to C and I currently have some problems. Please read the following code:

int main (int argc, char *argv[]) { int j = 2; int i = 100; int *pi = &i; pi = &j; //those 2 lines should do nothing, in my opinion pi = &i; // pi[1] = -4; printf("i = %d, j = %d, *pi = %d\n", i, j, *pi); return EXIT_SUCCESS; } 

The code does not work with SegFault. Some research using gdb:

 (gdb) print &j $1 = (int *) 0x7fffffffde80 (gdb) print &i $2 = (int *) 0x7fffffffde84 

However, without two lines, the code works fine, because I and j seem to be changing memory locations - but why ??

 (gdb) print &j $1 = (int *) 0x7fffffffde84 (gdb) print &i $2 = (int *) 0x7fffffffde80 

I asked my teacher, but, unfortunately, she had no idea.

Thanks in advance!

EDIT: working fine, I mean printf print: i = 100, j = -4, * pi = 100 - pi [1] points to j, it would seem

The question is, why do these 2 lines change something?

+5
source share
4 answers

With my compiler, it looks like this:

Of course, pi[1] and &pi[1] are undefined behavior.

Setting a breakpoint on pi[1] = -4; and start the program:

This is the result with pi = &j; pi = &i; pi = &j; pi = &i;

 Breakpoint 1, main (argc=1, argv=0x7fffffffe428) at tmp.c:12 12 pi[1] = -4; (gdb) p &j $1 = (int *) 0x7fffffffe334 (gdb) p &i $2 = (int *) 0x7fffffffe330 (gdb) p &pi $3 = (int **) 0x7fffffffe338 (gdb) p &pi[1] $4 = (int *) 0x7fffffffe334 (gdb) c Continuing. i = 100, j = -4, *pi = 100 [Inferior 1 (process 2890) exited normally] (gdb) 

&pi[1] randomly points to j

This is the result without pi = &j; pi = &i; pi = &j; pi = &i;

 12 pi[1] = -4; (gdb) p &j $1 = (int *) 0x7fffffffe33c (gdb) p &i $2 = (int *) 0x7fffffffe32c (gdb) p &pi $3 = (int **) 0x7fffffffe330 (gdb) p &pi[1] $4 = (int *) 0x7fffffffe330 (gdb) c Continuing. Program received signal SIGSEGV, Segmentation fault. 0x000000000040056d in main (argc=1, argv=0x7fffffffe428) at tmp.c:13 13 printf("i = %d, j = %d, *pi = %d\n", i, j, *pi); (gdb) p pi $5 = (int *) 0x7ffffffffffc 

With pi[1] = -4 (0xfffffffc) pointer pi modified to indicate a page on which the process cannot be read, so a segmentation error occurs.

You did not print pi , &pi and &pi[1] (which is UB), which would be interesting.

The answer to your question:

The compiler can decide where and in what order it transfers the variables in the stack frame. When you change the source code of a function, the compiler may decide differently. In addition, &pi[1] can point anywhere, as this behavior is undefined.

+1
source

pi is a pointer, and you make it a pointer to an integer later when you do

 pi[1] = -4; 

You gain access to memory that is not under your control, or memory that is not allocated by you, so it leads to undefined behavior, and therefore to a seg error.

+14
source

Statement pi[1] = -4; causes undefined behavior. Anything could happen. You may get expected or unexpected results.

pi[1] = -4; equivalent to *(pi+1) = -4; . One pointer after object i allowed, but dereferencing it calls undefined.

C11: 6.5.6 Additive operators:

7 For the purposes of these operators, a pointer to an object that is not an element of the array behaves in the same way as a pointer to the first element of an array of length one with the type of the object in the form of its element type,

8 If both the pointer operands and the result point to elements of the same array object or one after the last element of the array object, the evaluation should not lead to overflow; otherwise, the behavior is undefined. If the result indicates one after the last element of the array object, it should not be used as the operand of the unary * operator that is evaluated .


The question is, why do these 2 lines change anything?

Answer: due to undefined behavior .

+9
source

I could guess that pi=&j does not allow the compiler to pass j registration memory. Thus, with it, pi[1] is a reference to j , but without it, j is in the register and pi[1] is a reference to the value of the previously saved register ebp . As ebp becomes garbled, the process crashes when tryng returns with main() .

Having said that, I have to repeat what others have said: this behavior is undefined in both cases.

0
source

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


All Articles