Solved

How to protect aagainst string variable overwriting another variable?

Posted on 2004-04-04
8
284 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

0
Comment
Question by:steveresch
  • 2
  • 2
  • 2
  • +2
8 Comments
 
LVL 15

Expert Comment

by:lakshman_ce
Comment Utility
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
0
 
LVL 9

Assisted Solution

by:jhshukla
jhshukla earned 20 total points
Comment Utility
I believe the problem is here:
      TOT                  out_string
|--  8bytes  --|-----------------------  900bytes  -----------------------|
when you write to out_string probably you are running out of space and overwriting TOT. check if your output string is more than 900 chars long (return value of sprintf). btw it should overwrite _after_ or beyond the end of outstring but the compiler is allowed to place TOT after out_string which is the likely problem.
when you allocate 1500 bytes you create enough space for the entire string and your problem is solved. if you are not changing TOT throughout the prgm declare it as a const.

also, you can print addrs of TOT & out_string to see if my suggestion about compiler placing TOT after string was correct.

-- jaydutt
0
 
LVL 15

Expert Comment

by:efn
Comment Utility
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
0
 
LVL 12

Accepted Solution

by:
stefan73 earned 60 total points
Comment Utility
Hi steveresch,
> sprintf(out_string,

Never use sprintf, it's prone to buffer overflows. Use snprintf instead:
 int snprintf(char *s,  size_t  n,  const  char  *format,  /* args*/ ...);

So you'd do:
snprintf(out_string,sizeof(out_string),"%11.5d\t%11.5d\t%11.5lf\

Check snprintf's return value:
     The snprintf() function returns  the  number  of  characters
     formatted, that is, the number of characters that would have
     been written to the buffer if it were large enough.  If  the
     value  of  n  is  0  on a call to snprintf(), an unspecified
     value less than 1 is returned.

If it's bigger than your buffer size, you have a problem.

Cheers,
Stefan
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 15

Assisted Solution

by:efn
efn earned 20 total points
Comment Utility
Using snprintf is indeed another valid way to protect yourself, if it's available to you.  Unfortunately, it's not in the C++ standard library.  In Visual C++ 6.0, it appears as _snprintf.
0
 
LVL 17

Expert Comment

by:rstaveley
Comment Utility
> 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
0
 
LVL 17

Expert Comment

by:rstaveley
Comment Utility
...but really you ought to embrace IOStreams instead of all of this C malarky
0
 
LVL 12

Expert Comment

by:stefan73
Comment Utility
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
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now