memory leak - possible bug in <string>?

Is this a bug? A private string in a class is not cleaned up when the class is destroyed. Here is a simple example...

This is the class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <string>

namespace std
{

class test
{
	string x; // a private string variable 

	public:

	void set(const string& y); // a function to set x 

	test();

	~test();

};

};


The set function copies y into the private variable x;

1
2
3
4
5
6
7
8
9
10
11
12
13
#include "testsl.h"

using namespace std;

test::test() {} // dummy constructor

test::~test(){}  // dummy destructor

void test::set(const string& y)
{
	if (y=="set")
	x=y; // set x the private class string to the value of y 
}


1
2
3
4
5
6
7
8
9
10
11
12
int main()
{
	mtrace(); // start memory tracing

	test X; // create an instance of the class

	X.set("set"); // invoke the 'set' function

	muntrace(); // stop memory tracing
	
	return 0;
}


This is the mtrace output:

Memory not freed:
-----------------
Address Size Caller
0x00000000023fc460 0x1b at 0x7f575619126d

If the X.set() function is invoked without "set" as the argument, no leak occurs.

I have no idea what "mtrace"/"muntrace" do...but anyway, the problem is with them. There are no memory leaks with std::string, if there were, they would have been found long ago.
Thanks for your replay. However, the way I found the problem was when a program I wrote that creates and destroys a class with this 'feature' ended up consuming 1G of memory; this is clearly a memory leak and I traced the source of the problem to this.

The memory leak has nothing to do with mtrace which is simply a means of tracking malloc / free to make sure they are balanced. The leak is there whether memory tracing is used or not...
This may be a compiler issue; the addition of a set of braces changes the behavior. The problem only occurs when class is declared in the cope of main(). Declare it in braces or a subroutine and the error disappears.

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
#include <string>
#include <mcheck.h>

using namespace std;

class test
{

	string x;

	public:

	void set(const string& y)
	{
		x=y; // set x the private class string to the value of y
	}

	test() {}

	~test() {}

};


int main()
{
	mtrace();

	// produces a leak
		test X;
		X.set("Hi");

	{
	// doesn't produce a leak
		test Y;
		Y.set("Hi");
	}

	muntrace();

	return 0;
}


The OS is Ubuntu 10.04 LTS. The compiler is g++ 4.4.3

The workaround is therefore to declare the class inside braces or a subroutine...
Last edited on
Ah, the problem is that you are ending the memory trace *before* string's destructor (which frees the memory) is called.
Your explanation makes sense. Which means I need to look elsewhere for the leak...
Thanks for your help.
It's the scope of your variables.

the first calls the destructor at the program exit.

the second, you've enforced a scope with the braces, so the destructor
is called when the brace ends.

the string class is used by millions all over the world
if it had a leak, someone would have spotted it.

Topic archived. No new replies allowed.