?
Solved

How to protect aagainst string variable overwriting another variable?

Posted on 2004-04-04
8
Medium Priority
?
292 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 80 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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 12

Accepted Solution

by:
stefan73 earned 240 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 80 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: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

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

Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
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 video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

777 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