Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Possible memory leak

Status
Not open for further replies.

abcd12344445555

Programmer
May 10, 2009
24
BR
In the following class I'm using the C lib <time.h> .

The functions gmtime, ctime, and asctime return pointers to char/structs.

Am I responsible to clean the memory allocated by them? Is there any possible memory leak associated to the methods MyTimeClass::getDateAndTimeLocalTime() and MyTimeClass::getDateAndTimeUTC() described bellow?

Code:
Class MyTimeClass{
public:
 string getDateAndTimeLocalTime();
 string getDateAndTimeUTC();
 ...

private:
 time_t dateAndTime;
};

string MyTimeClass::getDateAndTimeLocalTime() {
  string result;
  result.append(ctime(&this->dateAndTime));

  return result;
}


string MyTimeClass::getDateAndTimeUTC() {
  string result;
  result.append(asctime(gmtime(&this->dateAndTime)));
  return result;
}



Thanks;
 
Short answer: no

ctime and gmtime return pointers to static structures and strings take copies of the text so there is no need to clean up.

What is worrying (to me at least) is returning strings on the stack. I've never been comfortable with the concept of returning objects on the stack. Just feels wrong even though both Stourstrop (not sure how you spell his name) and Lipman have that in examples in their books.
 
It seems to me that you have a C background. Right? That's why you feel uneasy about this approach.
It is strange indeed.

Thanks for the answer.
 
I have an Algol 60 background (i.e. I am absolutely ancient)

You are returning a structure on the stack which is pointing to the heap. That is OK in a single thread situation. I've seen this go wrong on several occasions in a multithread situation. The fix was to give it something to return that was not on the stack.

Having said that, what may look like convenience coding actually generates tons more code. Presumably the usage will be something like
Code:
string now = tc.getDateAndTimeLocalTime ();
Believe it or not, that actually generates more code than
Code:
void MyTimeClass::getDateAndTimeLocalTime(string& result)
{
  result.append(ctime(&this->dateAndTime));
}
...
string now;
tc.getDateAndTime (now);
May not look as elegant but if you're trying to squeeze every last ounce out of the machine and use your memory efficiently, then that is what you have to do.

The assignment of a string takes 17 bytes; using it as a parameter in a call only takes 15. The assignment routine takes 190 bytes (on MS), the parameter based one only takes 75.

You may hear the argument that memory is cheap and processors are fast. With efficient coding, you can squeeze a lot more into memory and get a 120MHz machine to outrun a 2GHz machine whilst performing the same functionality and using less memory.

Always take coding recommendations with a pinch of salt. Just because a guru recommends it doesn't mean it is right. Do your own experiments and draw your own conclusions.
 
Some notes:

Class std::string has value semantics. So it's possible and safety to return std::string objects as a function result. The only defect of this method: implicit extra call of std::string constructor is needed. Some compensation: probably, more clear code in function call context.
 
Sorry, but what do you mean by "Class std::string has value semantics"?

 
See, for example:
or

You (and me) can use std::string objects in the same manner as double or int values (to assign, to pass by value, to return from functions and so on). Actually std::string objects contents are allocated in the heap (in most of STL implementations) but don't worry: std::string constructors, destructors and assignment operators work like a charm (no memory leaks).
 
Some additions - std:string value semantics in examples:
Code:
char text[] = "text";
std::string s1(text);
s1 is not a reference to "text" literal or text array, it has its own copy of "text" (four chars sequence of 't', 'e', 'x', 't').
Code:
std::string s2;
s2 = s1;
Now s2 is not a reference to s1, it has it's own copy of the contents of (intact) s1.
Code:
std::string f() { return "text"; }
Create new std::string object with (copy of) "text" then pass it to the outer context(s) of this function call(s).
Code:
f();
The function f call is in void position (in expression statement, see semicolon after call;). Discard (deconstruct) returned std::string object (function value).
Code:
std::string s; // create (construct) an empty string object.
s = f();
Assign returned std::string object to s (make copy of the content of returned anonymous object) then discard (deconstruct) this object at (or just before;) semicolon position (end of assignment expression).

And so on...

In fact a std::string object has a pointer to the text contents dynamic array and carefully controls this memory chunk. As a result of this mechanics std::string object looks like a simple (so called plain old data) value (int or double, for example) in all contexts.

See your member functions (true C++;) code equivalent:
Code:
std::string MyTimeClass::getDateAndTimeLocalTime() 
{
  return ctime(&this->dateAndTime));
}


std::string MyTimeClass::getDateAndTimeUTC() 
{
  return asctime(gmtime(&this->dateAndTime));
}
No memory leaks or orphan references in this code (see examples above)...
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top