Memory Leaks. String Help

So, I'm having a problem actually understanding memory leaks I suppose. I thought I had a grasp, but I was mistaken. Visual Leak Detector has detected 5 leaks in my code. I would post the VLD output, but it is too long. So, I will simply highlight the lines of code it says are causing leaks in the following code segments.

The first is simply in the declaration of strings.
 
string temp, originalFilename, logFilename; //MEMORY LEAK 


Second, the leak is traced from this call (ofilename is a char*, if it's important I can show where and how it is accessed and set)
 
originalFilename = getOriginalFilename( ofilename ); // MEMORY LEAK 

Here is getOriginalFilename function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//Get the original base filename so we can rename
// multiple files based on this.
string getOriginalFilename( char* ofilename )
{
	stringstream buffer;
	string       temp, result;

	buffer.str("");
	buffer << ofilename;
	temp = buffer.str();

	if( temp.substr(temp.length() - 5, 5) == ".pcap" ) 
	{
		buffer.str("");
		buffer << temp.substr(0, temp.length() - 5);
		result = buffer.str(); //MEMORY LEAK
	} 
	else 
	{
		result = temp;
	}

	return result;
}


The final leak is very similar to the above leak. If you guys could help me out at understanding the WHY and how of this, that would be great. The best learning tool is an example such as the ones above. Thanks in advance.
Last edited on
It is strange. Only leak which could happens is with ofilename c-string if you have created it using new.
In all other cases there should not be any leaks, unless standard library have them, which it should not.
For clarity and completeness, here is declaration and initialization of ofilename

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int main(int argc, char **argv)
{
        char	*ofilename=NULL;

	for(i = 1; i < argc; i += 2)
	{
		switch (argv[i] [1])
		{

			case 'o': //Output Filename
			{
				ofilename=argv[i+1];
			};
			break;
                }
        }

        //...rest of code here...

        return 0;
}
Last edited on
you do know that you can assign a string to another string, ¿right?
Also, there is a string (const char* s); constructor
you do know that you can assign a string to another string, ¿right?
Also, there is a string (const char* s); constructor


Yes, I know. Which part of the code shown are you referring to? Keep in mind this code is slightly out of context (As the actual program is a couple thousand lines of code).
The stringstream has no purpose
1
2
3
4
5
6
7
8
9
/*	buffer.str("");
	buffer << ofilename;
	temp = buffer.str();*/
temp = ofilename;

		/*buffer.str("");
		buffer << temp.substr(0, temp.length() - 5);
		result = buffer.str(); //MEMORY LEAK*/
result = temp.substr(0,temp.length()-5


> Keep in mind this code is slightly out of context (As the actual program is a couple thousand lines of code).
¿Did you bother to verify that the snip that you posted does reproduce your issue?
The 2 lines you've kept from that segment of code completely change what is returned through result. I'm not sure if you meant for that to happen or not but the purpose of that function is to return the actual name of the file, minus any file extension, because the program later needs to append an incremented number to the end of the file as it continues to create them, ex: If the input in ofilename is "C:\filename.pcap" then it should return "C:\filename". However, I see what you are saying, that there is probably a way to do it without a stringstream. (See below)

And yes, it's been verified that the code shown, by itself, does reproduce the error. Here is an entire listing of a C++ program that creates two memory leaks.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <string>
#include <sstream>
#include <vld.h>

using namespace std;

//Get the original base filename so we can rename
// multiple files based on this.
string getOriginalFilename( char* ofilename )
{
	string       temp, result;

	temp = ofilename;

	if( temp.substr(temp.length() - 5, 5) == ".pcap" ) 
	{
		result = temp.substr(0, temp.length() - 5); //MEMORY LEAK
	} 
	else 
	{
		result = temp;
	}

	return result;
}

int main(int argc, char **argv)
{
	char	*ofilename=NULL;
	string	originalFilename; //Memory Leak

	for(int i = 1; i < argc; i += 2)
	{
		switch (argv[i] [1])
		{
			case 'o': //Output Filename
			{
				ofilename=argv[i+1];
			};
			break;
        }
    }

	originalFilename = getOriginalFilename( ofilename ); //Leak trace

    VLDReportLeaks();

    return 0;
}
Last edited on
Nobody has a clue?
Does the standard allocator for string use memory pooling?

Many implementations of the C++ standard libraries use their own memory pool allocators. Memory for quite a number of destructed objects is not immediately freed and given back to the OS, but kept in the pool(s) for later re-use. The fact that the pools are not freed at the exit of the program cause Valgrind to report this memory as still reachable. The behaviour not to free pools at the exit could be called a bug of the library though.

Using GCC, you can force the STL to use malloc and to free memory as soon as possible by globally disabling memory caching. Beware! Doing so will probably slow down your program, sometimes drastically.

http://valgrind.org/docs/manual/faq.html#faq.reports
Topic archived. No new replies allowed.