How does the value of this variable change in my C code?

I ran into a very strange problem in C that I had never encountered before. I narrowed it down to the next very simple fragment.

Variables are global and have the type:

int cpd; int nPart; 

And here is the corresponding piece of code, which I gradually divided to the minimum necessary to create the problem:

  printf("\ncpd1: %d\n",cpd); int p; for(p=1;p<=nPart;p++) { printf("\ncpd2: %d\n",cpd); exit(0); } 

... I get the output:

 cpd1: 17 cpd2: 0 

How is this possible ?! cpd was not reassigned, NO functions were called ... but has this changed? AS?!?!

It has quieted me for quite some time ... ... so any ideas?

Thanks for your time, Ben.

EDIT: and when I remove -02 from the makefile arguments in gcc, BOTH print sentences tell me cpd = 0!

EDIT: Well, I just found that a variable declared globally once, initialized as 4.0, and then never been changed, now looks like 1.51086e-311 ... Something very wrong somewhere ...

EDIT: SOLVED !: I had an array of size 1000, which should have been larger than 4000, and trying to write this distorted the memory around it. The fact is that this array is NOT accessible anywhere next to these print operations, but it is available in the same function, but much earlier (a big function!). The strange mismatch between print statements should be some kind of strange artifact of using -O2, since without -O2 both cpd prints print a damaged version. Thanks to everyone, I would not have managed this without your help!

+4
source share
7 answers

Damage to stack frames due to buffer overflows is a common explanation for this. Here is an example:

 #include <stdio.h> #include <string.h> int main() { int cpd; char msg[4]; cpd = 17; printf("%d\n", cpd); strcpy(msg, "Oops"); printf("%d\n", cpd); return 0; } 

Conclusion:

 17 0 

The msg line buffer is too short in character, the line delimiter overwrites the value "cpd".

The best way to find the reason is to use the interrupt function of the debugger. Set a regular breakpoint on the function entry point. Then find the address of the variable "cpd" and set a breakpoint on it on it. The debugger will stop as soon as the cpd value changes.

Remember that this will not necessarily work in optimized code, the value of "cpd" can be stored in a register. This is another possible explanation of why its meaning is different in individual statements.

+13
source

The only possible reason I can think of is because you specified another local int cpd variable. As an example, I took your code and modified it a bit to add another cpd int declaration and left it uninitialized:
I had to set nPart = 1 so that the for loop ran at least once

 #include <stdio.h> int cpd; int nPart = 1; int main (int argc, char ** argv) { printf("\ncpd1: %d\n",cpd); int cpd; int p; for(p=1;p<=nPart;p++) { printf("\ncpd2: %d\n",cpd); break; } } 

When I ran it, I got the following result:
cpd1: 0

cpd2: 2130567168

As expected, the global cpd variable is 0, the local cpd is not initialized, and can be almost any 32-bit value.

+5
source

What is published cannot do this. The only explanation is that something else changes cpd, or cpd has multiple instances.

+3
source
 int main() { int cpd = 13; int nPart = 17; printf("\ncpd1: %d\n",cpd); int p; for(p=1;p<=nPart;p++) { printf("\ncpd2: %d\n",cpd); } exit(0); } 

This compiles and works with the expected output for me. Did I incorrectly reproduce your example or the lack of a closing bracket at the end of your for (and including subsequent exit(0) target?

Edit: suppose that includes.

+3
source

You need to publish a complete, minimal, compiled program. For example, the following program:

 #include <stdio.h> #include <stdlib.h> int cpd = 17; int nPart = 10; int main(void) { int p; printf("\ncpd1: %d\n",cpd); for(p=1;p<=nPart;p++) { printf("\ncpd2: %d\n",cpd); exit(0); } return 0; } 

prints 17 twice.

Note:

  • nPart initialized to> = 1, otherwise the loop will not be executed even once.
  • I have included stdio.h and stdlib.h for printf() and exit() respectively.
  • I left the call exit(0); inside the loop - not sure why you have one, since this means that the loop will be executed no more than once.
+2
source

An unintelligible variable can have any value, usually it will be set to zero in the debug assembly, but you cannot rely on it.

0
source

If the smallest piece of code you posted really reproduces the problem, then the only explanation here is that your compiler is hopelessly broken and generates meaningless broken code.

However, I strongly suspect that the fragment you posted is actually not filled (obviously, it does not compile), and the problem lies somewhere in the code that you missed.

0
source

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


All Articles