A quick question on new/delete and alloc/free

Hello,

I have a question regarding the new/delete operator compared to alloc/free.

When dynamicly allocating memory for a char*, I normaly use calloc so all reserved bits are set to zero, so I don't have to bother with nulltermination.

Does char *string = new char[20] only reserve 20 items with the size of a char or does it also sets all bits in that memoryarea to zero?

If not can memset be used on this memory to accomplish that?
And if memset or any other method of zeroing out the allocated memory is possibly, can the new operator be overloaded for the native char type to do this work on its own?

Thanks for your answers in advance.
I think new does initialize memory. Even if it didn't, you can use memset().
You can't overload constructors for the native types.
ok, so we can't overload the new constructor, but we could force the usage of an own constructor.

First we create a new class for which we define our own new operator.
Then we create a new object of that class and force it on the char* by casting.

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

using namespace std;

class c{
	public:
		void* operator new[ ] (size_t);
		void operator delete[ ] (void*);
};

void* c::operator new[ ] (size_t  allocSize)
{
	cout << "Use operator new[ ] from class C\n";

	char *charptr = new char[allocSize];
	memset(charptr, 0, allocSize+1);

	return charptr;
}
  
void c::operator delete[ ] (void *p)
{
	cout << "Use operator delete[ ] from class C\n";
    // here, real usage would include deallocation
	// but we never use these destructor,
	// instead we use standard destructor for char.
	::operator delete[ ] (p);
}

int main()
{

  char *a = (char*)new c[10];
  
  a = "Hallo";
  cout << "a:" << a << ":a" << endl;
  
  char *b = new char[10];
  cout << "b:" << b << ":b" << endl;

  delete[ ] a;
  delete[ ] b;
}


The code works.

char *b = new char[10]

Did allocate memory, but didn't zero it out.

char *a = (char*)new c[10]

Also allocates the memory, but here it's set to zero.
Since we know that we created memory for char* we should be able to cast to char* without being to much troubled.
new c[10] returns the internally created charptr which is actually a char* so we should have no trouble.

But maybe I don't see some obstacles that could be there.

And since we used new char[] in our own new we should be able to used the standard delete [] operator as well.
Last edited on
That looks overly complicated. If you really want to do it like that, why not use the simplest way:
1
2
3
4
5
6
template <typename T>
T *talloc(size_t s){
	T *r=new T[s];
	memset(r,0,s*sizeof(T));
	return r;
}

Note that on line 35 you created a memory leak. I don't know why line 41 didn't cause a segmentation fault.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main()
{

  char *a = (char*)new c[10]; //created a char* pointing to 10 chars
  
  a = "Hallo"; //point a to some random read-only string (as helios said, you can no longer access the stuff you have made with new above! and no longer delete it either)
  cout << "a:" << a << ":a" << endl;
  
  char *b = new char[10]; //create b
  cout << "b:" << b << ":b" << endl; //...

  delete[ ] a; //delete something you didn't allocate with new..."Hallo"
  delete[ ] b; //works, you allocated it with new
}
my, my, your right, created constant string iteral and changed adress of a.
strange program didn't produce segfault error.
Thanks for the template advice, never used templates, seems to be a concept I should learn to use.

How would a call to this template look like?

If I'am understanding the implicit template specialization right it should be as easy as:

 
char *charptr = talloc(10);


right?
Last edited on
Ok, seems to be not so easy.

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

template <typename T>
T *talloc(size_t s){
	T *r=new T[s];
	memset(r,0,s*sizeof(T));
	return r;
}

using namespace std;

int main()
{
  char *a = talloc((size_t)6); // talloc(6) produced error "no matching function for call to `talloc(int)'"
		   // talloc((size_t)6) produced error "no matching function for call to `talloc(size_t)'"
  strncpy(a, "Hallo", 5);
  cout << "a:" << a << ":a" << endl;
}


Where exactly has a template to placed? Maybe I'm just displacing the template.

Hmm, T *r=new T[s] should be char *chrptr = new char[s] in runtime.
This would require T to be char.
If T is char then T *talloc would be char *talloc().
But wouldn't that require me to call something like this:

char a = talloc(5) so type of T will be char? But then I would return a char* to a char?

I'm confused.

Ok, got it, implicite specialization isn't possible in this special case.

char *a = talloc<char>(6)

This did indeed work, as required. Thanks helios.
If I could rate you at this site I would give you a straight A+ for all the help you provide.
Last edited on
Thanks for this info. It was very helpfull.
Topic archived. No new replies allowed.