I need some help to find a memory leak in my C++ code. I try to put these lines in my constructor but it causes a memory leak because of lines 2 and 3 in the constructor:
Myclass::Myclass()
{
ACE_Time_Value tm = ACE_OS::gettimeofday();
m_obj.firstStr() = tm.sec();
m_obj.secondStr() = tm.usec();
}
Here, firstStr() and secondStr() are both methods which return std::string& in another class.
Any suggestion what this memory leak depends on? I'm not sure if these 2 lines are the actual cause of the memory leak but Valgrind points to these two lines and I don't know how to find the leak.
I'm no expert on ACE but it seems unlikely that tm.sec() returns a string - far more likely it returns an integer (in fact it does - it returns a long). In that case, when you call your functions and assign to them you are essentially calling the string's assignment operator which assigns a single character (encoded in the long) to the string. This is almost certainly not what you want, but it should not cause a memory leak.
In other words, you are effectively doing this:
int main() {
string s = "foobar";
cout << s << endl;
s = 65L;
cout << s << endl;
}
which prints:
foobar
A
but does not leak memory.
If you are using any memory leak detectors( and still suspectful) then the next best possible way is to overload your new and delete operator in your debug build and log all your memory allocations and deallocations. One possible help
I think when
ACE_Time_Value tm = ACE_OS::gettimeofday();
is called space string is allocated
and assigned to first and second string
But when constructor is done ACE_Time_Value destructor is called which deleted the string allocated.
But they are still referencing to First and second string.
Hence the leak.
Trying coping the values. to prevent the leak.
Related
I have a memory leak detector tool which tells me below code is leaking 100 bytes
#include <string>
#include <iostream>
void setStr(char ** strToSet)
{
strcpy(*strToSet, "something!");
}
void str(std::string& s)
{
char* a = new char[100]();
setStr(&a);
s = a;
delete[] a;
}
int main()
{
std::string s1;
str(s1);
std::cout << s1 << "\n";
return 0;
}
According to this point number 3 it is leaking the amount I allocated (100) minus length of "something!" (10) and I should be leaking 90 bytes.
Am I missing something here or it is safe to assume the tool is reporting wrong?
EDIT: setStr() is in a library and I cannot see the code, so I guessed it is doing that. It could be that it is allocating "something!" on the heap, what about that scenario? Would we have a 90 bytes leak or 100?
This code does not leak and is not the same as point number 3 as you never overwrite variables storing pointer to allocated memory. The potential problems with this code are that it is vulnerable to buffer overflow as if setStr prints more than 99 symbols and it is not exception-safe as if s = a; throws then delete[] a; won't be called and memory would leak.
Updated: If setStr allocates new string and overwrites initial pointer value then the pointer to the 100 byte buffer that you've allocated is lost and those 100 bytes leak. You should initialize a with nullptr prior to passing it to setStr and check that it is not null after setStr returns so assignment s = a; won't cause null pointer dereference.
Summing up all the comments, it is clear what the problem is. The library you are using is requesting a char **. This is a common interface pattern for C functions that allocate memory and return a pointer to that memory, or that return a pointer to memory they own.
The memory you are leaking is allocated in the line char* a = new char[100]();. Because setStr is changing the value of a, you can no longer deallocate that memory.
Unfortunately, without the documentation, we cannot deduce what you are supposed to do with the pointer.
If it is from a call to new[] you need to call delete[].
If it is from a call to malloc you need to call std::free.
If it is a pointer to memory owned by the library, you should do nothing.
You need to find the documentation for this. However, if it is not available, you can try using your memory leak detection tool after removing the new statement and see if it detects a leak. I'm not sure if it is going to be reliable with memory allocated from a library function but it is worth a try.
Finally, regarding the question in your edit, if you leak memory you leak the whole amount, unless you do something that is undefined behavior, which is pointless to discuss anyway. If you new 100 chars and then write some data on them, that doesn't change the amount of memory leaked. It will still be 100 * sizeof(char)
I have copied this code from a site.
But I am having problems understanding it properly.
Please can you help me these doubts.
I have written them as comments.
#include<iostream>
using namespace std;
#include<cstring>
class strings
{
char *m_string;
int m_length;
public:
strings(const char* str = "")
{
m_length = strlen(str) + 1;
m_string = new char[m_length];
strncpy(m_string,str,m_length);
m_string[m_length - 1] = '\0';/*1*/
}
~strings() /*2*/
{
delete[] m_string;
m_string = 0;/*3*/
}
char* get()
{
return m_string;
}
};
int main()
{
strings cstring("Alex");
cout << "Hi I am " << cstring.get();
cout << "\nsup";
strings cstrings1("Shady");
cout << "\nyo " << cstrings1.get();
return 0;
}
why is the code asking me to do this. When I removed this line code still worked perfectly fine
why are they using the destructor? Again not using it does seem to have any effect on the program
Also what is the use of doing this when I just used the delete keyword
Can you guys please explain to me in easy way really what do I use a destructor for? Thank you so much
1) Ensures that the string is null terminated - see http://www.cplusplus.com/reference/cstring/strncpy/ as to why this might not always be the case
2) It allows the delete operator to free up the allocated heap memory - otherwise your program will have a memory leak
3) Just good practice to avoid deleting previously deleted memory - this avoids undefined behaviour.
This is how to misuse C idioms in C++ to produce dangerous, error-prone programs. Don't use this as an example of how to write C++ effectively. To answer your specific questions:
In this case, explicitly terminating the C-style string is pointless. If you didn't know whether the input was small enough to fit in the array, then strncpy might truncate the string, and not put a zero terminator on the end; so, if you use strncpy, you must either terminate it yourself, or take some other action if it was truncated. But here you just allocated a large enough array, measured using strlen. You might as well use strcpy, memcpy or std::copy (which assume a large enough output array) instead of strncpy. Or, since this is C++ not C, throw the whole thing away and use std::string.
The destructor is needed to deallocate the memory allocated in the constructor. Otherwise you have a memory leak. As you say, this doesn't seem to have an effect - unless the program keeps allocating and leaking memory, in which case you'll eventually run out. You'll also need to define or delete a copy constructor and copy-assignment operator (per the Rule of Three), otherwise the class is not safe to copy.
That's pointless, since the pointer itself is about to be destroyed along with the rest of the class object. In some circumstances, if the pointer is going to persist after the delete, setting it to null would allow you to check whether or not it points to anything. But, unless you enjoy long debugging sessions, you shouldn't be using pointers for memory management anyway; use RAII types like smart pointers or std::string.
The following code resolves the problem of removing the duplicate characters in a string.
void removeDuplicatesEff(char *str)
{
if (!str)
return;
int len = strlen(str);
if (len < 2)
return;
const int sz = (1<<CHAR_BIT);
bool hit[sz] = {false};
int tail = 0;
for (int i=0; i<len; ++i)
{
if (!hit[str[i]])
{
str[tail] = str[i];
++tail;
hit[str[i]] = true;
}
}
str[tail] = 0;
}
After setting str[tail]=0 in the last step, if char *str does contain duplicate characters, its size will be smaller, i.e. tail. But I am wondering whether there is a memory leak here? It seems to me that, later, we cannot releasing all the spaces that is allocated to original char *str. Is this right? If so, how can we resolve it in such situations?
It seems to me that, later, we cannot releasing all the spaces that is allocated to original char *str. Is this right?
No. The length of a zero-terminated string is completely decoupled from the size of the allocated memory buffer, and the system treats it separately. As long as every allocation is followed by a symmetrical deallocation (e.g. there’s a free for every malloc operation), you’re safe.
But I am wondering whether there is a memory leak here?
Arguably, yes, this is still a leak since it (temporarily) uses more memory than required. However, that is usually not a problem since the memory gets released eventually. Except in very special circumstances, this would therefore not be considered a leak.
That said, the code is quite unconventional and definitely longer than necessary (it also assumes that CHAR_BIT == 8 but that’s another matter). For instance, you can initialise your flag array much easier, saving a loop:
bool hit[256] = {false};
And why is your loop going over the string one-based, and why is the first character handled separately?
No, there is no leak. You only modify the contents of the array by putting in 0 and not its length.
Also you shouldn't initialize your hit array by assignment with the for-loop. A standard initialization
bool hit[256] = { 0 };
would suffice and can be replaced by your compiler by the most efficient form of initialization.
There is no memory leak in your case. Memory leak happens when you allocate memory from head and not freeing after using it. In your case you are not allocating any memory from heap. You are using local variables which are stored in stack and freed when control returns from that function.
What you are doing is just changing the placement of the terminator character. It doesn't actually change the size of the allocated memory. It's actually a very common operation, and there is no risk of memory leak from doing it.
No, you will not have a memory leak. Performing a delete [] or free() on str will deallocate all allocated memory just fine because that information is stored elsewhere and does not depend on the type of data being stored in str.
But I am wondering whether there is a memory leak here? It seems to me that, later, we cannot releasing all the spaces that is allocated to original char *str
There's probably no problem here. the storage for str has been allocated in one of the following ways:
reserved space on the stack
malloc space on the heap
reserved space in the data segment.
In the first case, all of the space disappears when the stack frame unwinds. In the second case, malloc records the number of bytes allocated (usually in the memory location just before the first byte pointed to by the malloc return value. In the third case, the space is allocated only once when the program is first loaded.
No possibility of a leak there.
Ok, so i'm just learning about memory leaks. i ran valgrind to find memory leaks. i get the following:
==6134== 24 bytes in 3 blocks are definitely lost in loss record 4 of 4
==6134== at 0x4026351: operator new(unsigned int) (vg_replace_malloc.c:255)
==6134== by 0x8048B74: readInput(char&) (in calc)
so does that definitively mean the leak is in my readInput function? if so, how do i get rid of the memory leaks? here's the offending function:
double* readInput(char& command){
std::string in;
std::getline(std::cin, in);
if(!isNumber(in)){
if(in.length()>1){
command = 0;
}
else{
command = in.c_str()[0];
}
return NULL;
}
else{
return new double(atof(in.c_str()));
}
}
thanks!
// ...
return new double(atof(in.c_str()));
// ...
new acquires resource from free store which is being returned. The returned value must be deallocated using delete to avoid memory leak.
If you are calling the function in a while loop, number should be definitely deallocated using delete before running the loop next time. Just using delete once will only deallocate the very last source acquired.
Edit:
// ....
while( condition1 )
{
double *number = NULL ;
number = readInput(command) ;
if( condition2 )
{ .... }
else
{ .... }
delete number ; // Should be done inside the loop itself.
// readInput either returns NULL or a valid memory location.
// delete can be called on a NULL pointer.
}
You're returning a new double... When is that freed? You do call delete on it at some point... right?
Personally, I would recommend just returning non-zero for success and zero for failure and put the value in a double * (or double &) parameter. That way you don't need to bother with new at all.
You return a newly allocated double. Do you delete it somewhere?
Why are you returning a pointer to a newly allocated double? Why not just return a double? It isn't a big deal to return an eight-byte temporary value, and the caller can decide what it wants to do with it (including allocating a new double on the heap if it likes). Assuming the values aren't large, I'd much rather return a temporary. Having the new closer conceptually to the actual use makes the memory management easier.
Moreover, allocating large numbers of very small blocks can lead to inefficient heap use and heap fragmentation, so that the program might run out of memory when it wouldn't otherwise, and might not be able to allocate a large chunk even if it looks like there's plenty left. This may or may not matter (and the extra time needed to allocate memory may or may not matter, especially in a function whose running time is probably dominated by I/O). This is likely micro-optimization, but if there is no good reason for such small allocations you may as well get in the habit of not using them.
Hey all, just wondering whether the following would cause a memory leak?
char* a = "abcd"
char* b = new char[80];
strcpy(b, a);
delete[] b;
Will it delete the whole block of 80 or just the 4 characters copied into it by strcpy? Thanks!
You allocated 80 bytes into b, so delete[] will free 80 bytes. What you did with the array in the meantime is irrelevant.
(Unless, of course, you corrupted the heap, in which case delete[] will probably crash.)
EDIT: As others have pointed out, since b is an array, you need to use delete[] b; instead of delete b;. Some implementations might let you get away with that, but others won't, and it would still be wrong.
A memory leak is when you don't free memory. Just because you allocated more than you need doesn't mean it a memory leak. What you do with your memory is up to you.
Though that should 1) be delete [] b;, or you get undefined behavior, and 2) Be a std::string or std::vector, so you don't both manage and use a resource.
The allocation system will take care of remembering how long the allocations are. The contents don't matter at all.
However, you do need to call the right delete operator. In this case since you allocated new[] you need to delete[].
The last line should be:
delete[] b;
If you allocate one item use delete, if you're allocating an array use delete[].
Since this is tagged C++, here's the C++ version - good to understand memory management via new/delete, but better to avoid doing it by hand using RAII.
#include <string>
#include <iostream>
using namespace std;
int main()
{
string a("abcd");
string aCopy(a);
cout << aCopy << endl;
const char* b(aCopy.c_str());
cout << b << endl;
}