Static Map not usable in global New?

Using a std::map as in the line marked with /* X */ below crashes the code during execution. If this line is erased, the code runs but creates the following unexpected output:

a= 5
m[0]= 3


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <map>
using namespace std;

static int a = 0;
static map<size_t, size_t> m;

void * operator new( size_t length ){ 
	m[0] = 5;  /* X */
	a = 5;
	return malloc( length );
}

void f(){
	a = 3;
	m[0] = 3;
}

int main(){
	f();
	cout << "a= " << a << endl;
	cout << "m[0]= " << m[0] << endl;
}



Could somebody please give me a hint what is going wrong here? Many thanks!
Last edited on
When you evaluate m[0] = 3; within f(), std::map creates a tree node with the key 0 and with value 3.

That node is allocated by calling new (unless you provide a non-default allocator to std::map at line 6).

That call to new calls m[0] again, which crashes your program, or, with that line commented out, executes a=5, which you then see in the output at line 21.
In line 16, you insert a new element into the map, for which it tries to allocate memory using new.
Your new operator also tries to insert the same element every time, thus entering infinite recursion.
Edit: too slow.
Last edited on
Let me give you a hint before you do anything else with your program. I read that in a book:

"NEVER OVERLOAD new AND delete OPERATORS"!!!

And the creator of C++ said something I liked: "Overloading new and delete operators is not for the faint-hearted."

When you fail in solving such a simple problem, I'd really suggest that you don't mess with new and delete operators.
----------------

Anyway,

static variables should not be defined in the global scope, but only initialised. Here's an example:

1
2
3
4
5
6
7
class MyClas
{
public:
static int myint;
};

int MyClass::myint;


I hope this helps and you got the idea :-)
closed account (zb0S216C)
TheDestroyer wrote:
"NEVER OVERLOAD new AND delete OPERATORS"!!!

Agreed. I bet the OP is wondering why. Here's why:

Any classes or functions that rely on the global operator new (such as std::vector<T>) are going to fail. If you insist on overloading the global operator new, then ensure that it doesn't interfere with the allocations of dependant classes and functions. Alternatively, consider module programming. This incorporates the use of namespaces:

1
2
3
4
namespace Allocator
{
    void *operator new(std::size_t, /*Other parameters*/);
}

This will force you to qualify your version of operator new with Allocator. Of course, using namespace Allocator will break whole idea, and you'll be back at square 1.

Wazzak
Another alternative is to use your own allocators for all containers and other allocator-aware classes.

Some stuff at my work is done that way (not because we want to overload global new, but because we have various special memory access requirements)
That was very helpfull!
Thanks!
Seppel.
Topic archived. No new replies allowed.