We help IT Professionals succeed at work.

Check out our new AWS podcast with Certified Expert, Phil Phillips! Listen to "How to Execute a Seamless AWS Migration" on EE or on your favorite podcast platform. Listen Now

x

How to protect aagainst string variable overwriting another variable?

steveresch
steveresch asked
on
Medium Priority
315 Views
Last Modified: 2010-04-01
I am working on a pretty simple program in MS Visual C++ 6.0. Its basically a C program, but I like the IDE of C++. Anyway, I came across a very unexpected bug. I have the following relevant variable:

 double TOT = 100000;
 char out_string[900];

Never in the entire program do I change the value of TOT.
Later in the program, I have a line of code to change the value of out_string and write it to a txt file:


sprintf(out_string,"%11.5d\t%11.5d\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf",f,d,k1d,k2d,k3d,k1m,k2m,k3m,j1d,j2d,j3d,j1m,j2m,j3m,g,w,muT1d,muT2d,muT3d,muT1m,muT2m,muT3m);
outFile0 << out_string <<endl;

I am focusing on this  line because I had a strange bug where TOT was being reset to zero and I isolated this line as the cause by doing the following:

printf("---TOT =  %lf ---1",TOT);
sprintf(out_string,"%11.5d\t%11.5d\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf",f,d,k1d,k2d,k3d,k1m,k2m,k3m,j1d,j2d,j3d,j1m,j2m,j3m,g,w,muT1d,muT2d,muT3d,muT1m,muT2m,muT3m);
outFile0 << out_string <<endl;
printf("---TOT =  %lf ---2",TOT);

and getting the resulting output: ---TOT = 100000 ---1---TOT = 0.0000---2

So it turns out that if I shorten the string or change the definition to

char out_string[1500];

the problem is solved.

But for the future I'd like to know how I can protect against this apparent "overwriting" of the variable TOT.

Can anyone give an explanation of what happened, what I did wrong, why the compiler gave no warnings, and how I can protect against this in the future?

THanks!!

Steve

Comment
Watch Question

Can you plz tell where is the following code declared?
double TOT = 100000;
char out_string[900];


I have tested the following code
void main()
{

      double TOT = 100000;
       char out_string[900];
      int ,d,k1d,k2d,k3d,k1m,k2m,k3m,j1d,j2d,j3d,j1m,j2m,j3m,g,w,muT1d,muT2d,muT3d,muT1m,muT2m,muT3m
                //not initilized

      printf(out_string,"%11.5d\t%11.5d\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf",f,d,k1d,k2d,k3d,k1m,k2m,k3m,j1d,j2d,j3d,j1m,j2m,j3m,g,w,muT1d,muT2d,muT3d,muT1m,muT2m,muT3m);
      cout << out_string <<endl;

      printf("---TOT =  %lf ---1",TOT);
      printf(out_string,"%11.5d\t%11.5d\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf",f,d,k1d,k2d,k3d,k1m,k2m,k3m,j1d,j2d,j3d,j1m,j2m,j3m,g,w,muT1d,muT2d,muT3d,muT1m,muT2m,muT3m);
      cout << out_string <<endl;
      printf("---TOT =  %lf ---2",TOT);

}
I could see TOT as 10000.000000 in both cases

-Lakshman
Commented:
Unlock this solution with a free trial preview.
(No credit card required)
Get Preview
efn

Commented:
As jhshukla wrote, the program probably wrote beyond the bounds of the array.  Neither the compiler nor the run-time system protects you from errors of this kind in C++ (or C), as part of the language's philosophy of being efficient and close to the hardware.  You can protect against it by being aware of it and programming more carefully, or by using an object of a string class instead of a character array.  A string object manages memory for you, so you don't have to worry about problems like this.

--efn
Top Expert 2004
Commented:
Unlock this solution with a free trial preview.
(No credit card required)
Get Preview
efn
Commented:
Unlock this solution with a free trial preview.
(No credit card required)
Get Preview
> printf(out_string,"%11.5d\t%11.5d\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf\t%11.5lf",f,d,k1d,k2d,k3d,k1m,k2m,k3m,j1d,j2d,j3d,j1m,j2m,j3m,g,w,muT1d,muT2d,muT3d,muT1m,muT2m,muT3m);

use sprintf
...but really you ought to embrace IOStreams instead of all of this C malarky
Top Expert 2004

Commented:
rstaveley,
> ...but really you ought to embrace IOStreams instead of all of this C malarky
Good point. Additionally, this lot of identical fields is probably better printed in a loop.

Stefan
Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a free trial preview!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.