overrided the new [] operator

Pages: 12
is there a way to override the new[] to control how the constructor is called?
for example give a class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class foo
{
private:
	int a, b;
public:
	foo() : a(1), b(1) {}
	~foo() {}
};

int main(int argc, char* argv[])
{
	foo* x;
	x = new foo[10000]; // first allocate memory then change how the constructor called through a loop

	delete [] x;
	return 0;
}


Last edited on
You want to use placement new instead of overloading operator new[].
I don think that the placement new is the right approach. I know that during the code
x = new foo[10000];
Two operations occur.
First the code allocates at least enough memory for 10000 foo objects.
Next the code constructs 10000 foo objects.
What I would like to modify is the second part.

thanks again
Did you even look at any examples of how to use placement new?
Yes
placement new from what I saw is just putting data into a buffer. I do not want a buffer, and I do not want change the memory model. All I want is to change when and what new [] operator calls the constructor.
the code below is only to demonstrate my purpose.
1
2
3
4
5
6
7
8
9
 class foo
{
private:
	int a, b;
public:
	foo() : a(1), b(1) {}
	foo(int i) : a(i), b(0) {}
	~foo() {}
};

x = new foo[10000];//where foo[] might call foo(i) where i is a position of the foo object
Last edited on
If you don't want to store your objects in a buffer, then unfortunately you have no options. The only way to get what you want is to use placement new, or an array of pointers.
Yes
placement new from what I saw is just putting data into a buffer.

Placement new constructs an object at an existing memory location. It does not "put data into a buffer." If you want to divorce the construction of an object from the allocation of memory for an object as you seem to want to do, you must use placement new.

Your example is not complete. There is no sense of where you want a constructor to be called or how the array would be accessed. placement new is usually used in the context of a container, but that doesn't appear to be what you're doing.

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
#include <memory>

class foo
{
private:
    int a, b;
public:
    foo() : a(1), b(1) {}
    foo(int i) : a(i), b(0) {}
};

int main(int argc, char* argv [])
{
    // allocate the memory:
    const unsigned nFoos = 10000;
    void* rawMem = operator new(nFoos * sizeof(foo));

    foo* const beg = static_cast<foo*>(rawMem);
    foo* const end = beg + nFoos;

    // construct the elements:
    unsigned i = 0;
    foo* current = beg;
    while (current != end)
    {
        if (i % 2)
            new (current) foo(i);
        else
            new (current) foo();

        ++current, ++i;
    }

    // destruct the elements:
    current = beg;
    while (current != end)
        (current--)->~foo();

    // free the memory
    operator delete(rawMem);
}
I think that your code is closer to what I want. The only problem is that in the class I would have to create another class to create the array and prevent people from calling the new [] and delete [] operators on the foo class. is there a way to override the construction call in the new [] operator and the destruction call in the delete [] operator.
... to control how the constructor is called?
for example give a class

Can you elaborate on what you're trying to do? What do you want to change about the way the constructor is called? Change the order in which the array items are initialized? Use different constructors for different items in the array? Something else?
vickoza wrote:
is there a way to override the construction call in the new [] operator and the destruction call in the delete [] operator.
No, because you're confusing a few different things. There is "operator new" which only allocates memory, "placement new" which only calls constructors, and just plain "new" which does both. It is only possible to change the behavior of "operator new", but you want to change the behavior of "new".

I don't know what you are trying to do if you expect yourself to create the objects and others to clean them up. It makes no sense.
Last edited on
L B
I think now I understand there are two major pieces of code the following code calls
x = new foo[10000];
first it calls either
1
2
void* operator new[] (std::size_t size) throw (std::bad_alloc); //or 
void* operator new[] (std::size_t size, const std::nothrow_t& nothrow_value) throw();

then it calls
 
void* operator new[] (std::size_t size, void* ptr) noexcept;

where the second operation is what I need to override how should I override this code
What I want to do is to construct 10,000 foo objects in parallel though an array.
I am now worried about the parallel part just I what to knows how to change the loop when constructing objects
check if this is correct
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class foo
{
private:
	int a, b;
public:
	foo() : a(1), b(1)
	{}
	~foo() {}
	void *operator new[](size_t t)
	{
		long z = (t) / sizeof(foo2);
		long x = sizeof(long);
		void* p = malloc(t);
		foo* p2 = ((foo*)p + sizeof(long));
		for (int i = 0; i < z; i++)
		{
			p2 = new foo();
			p2 += sizeof(foo);
		}
		return p;
	}
};
then it calls

The expression new foo[10000] calls only one allocation function: void* operator new[] (std::size_t) (static member of foo if provided, global otherwise: note that your non-static member would never be called). Then it calls foo::foo() 10000 times, directly, with no other functions involved.

how to change the loop when constructing objects

don't use new, that's how std::vector and other containers do it.
Last edited on
can I prevent it from calling foo::foo() 10000 times if I move the calling of the constructor into the void* operator new[] (std::size_t)?
Last edited on
Not unless you read what we are writing.
I think that I should try to create a class like foobar to control the creation and destruction of foo objects and delete the void* opertator new [] (std::size_t)
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
class foo
{
private:
	int a, b;
public:
	foo() : a(1), b(1)
	{}
	~foo() {}
	void *operator new[](std::size_t t) = delete;
	void operator delete[] (void* ptr) = delete;
};
class foobar
{
public:
	static foo* CreateFooArray(int size)
	{
		foo* p = (foo*)malloc(size * sizeof(foo));
		foo* p2 = ((foo*)p + sizeof(long));
		for (int i = 0; i < size; i++)
		{
			p2 = new foo();
			p2 += sizeof(foo);
		}
		return p;
	}
	static void DestroyFooArray(foo* array, int size)
	{
		foo* p = array;
		for (int i = 0; i < size; i++)
		{
			p->~foo();
			p += sizeof(foo);
		}
		free(array);
	}
};
Deleting the local operator new doesn't prevent anyone from using the normal operator new.
I believe that it does prevent anyone from calling the code x = new foo[10000]; where x is a foo pointer. This code might be C++ 14 or C++ 11 code and might not compatible with older C++ compliers.
can I prevent it from calling foo::foo() 10000 times

Ah. Now we're getting somewhere. :)

So does this mean that you're okay with having the data in foo be uninitialized? If so then you could just not define a default constructor.

If class foo has a base class or class member data, then do they have default constructors? If so then you can't get away from the problem.

If foo has virtual functions then you must call the constructor.

If you don't construct the foo objects then what happens when they are destroyed? Will the destructor work? Will your solution even call the destructor?

For all of these reasons I think you may want to step back and reevaluate what you're trying to do. Do you really need to construct 10,000 foos? At that time? If so then you should let the constructor be called. Would a vector<foo> be more appropriate?
I have found that I can initialized the data in the void *operator new[](size_t t) but in doing so it recalls the constructors after the data has been allocated.

During my experiments using Visual C++ Express 2013 for desktop I found that t is the number of foo objects needed time the sizeof(foo) plus 4. I think that the 4 is there for telling how many objects are allocated for the array.

The purpose of this exercise is to find a way to initialize 10,000+ foo objects using a parallel process such as C++ AMP, OpenMP, Threading Building Blocks, or Microsoft's Parallel Patterns Library.

foo does not have any inheritance and so therefore no virtual functions and no base constructor

vector<foo> would not be ideal is this case because I do not have control of the construction objects. Also, this does not change once it is written. However if you are suggesting to still go with vector<foo> then I think writing a templated array class might be the best solution.
Pages: 12