Solved

How to protect aagainst string variable overwriting another variable?

Posted on 2004-04-04
8
289 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
ID: 10753988
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
ID: 10755139
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
ID: 10755446
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
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 12

Accepted Solution

by:
stefan73 earned 60 total points
ID: 10755459
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
 
LVL 15

Assisted Solution

by:efn
efn earned 20 total points
ID: 10755569
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
ID: 10755947
> 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
ID: 10755955
...but really you ought to embrace IOStreams instead of all of this C malarky
0
 
LVL 12

Expert Comment

by:stefan73
ID: 10756206
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

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
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 viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

820 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