0

what is the difference between this code:

void* raw_mem = operator new(sizeof(int)*4);
int *dynamicInt = static_cast<int*>(raw_mem);
dynamicInt[2] = 10;
operator delete(raw_mem);

and this code:

void* raw_mem = operator new[](sizeof(int)*4);//notice [] after new
int *dynamicInt = static_cast<int*>(raw_mem);
dynamicInt[2] = 10;
operator delete[](raw_mem);//notice [] after delete

are they strictly the same?

As per aschepler`s comment, my code is technically undefined behaviour. The working version of it is:

void* raw_mem = operator new(sizeof(int)*4);
int *dynamicInt = static_cast<int*>(raw_mem);
for(size_t i = 0;i<4;++i){
    new(&dynamicInt[i]) int(1);//initializes all elements to 1
}
//alternative version initializes only the first element:
//new(dynamicInt) int(10);
operator delete(raw_mem);
Matias Chara
  • 921
  • 6
  • 21
  • 1
    Regarding the "do any of them do the same as" bit, in this simple case yes. ***But*** if you use a class-type instead of `int`, more specifically a class-type with constructor and destructors, there's a definite difference. – Some programmer dude Jul 16 '20 at 17:45
  • 1
    Is that even legal code? Does new need to know what you're making a new whatever of? If an employee of mine wrote any of these versions, I'd be rather disappointed. The third one is the least evil, but why would you create the space in this fashion? If you need an array of ints, then create an array of ints. If you're later going to have to dump it to disk in raw form or something, then recast it at that time. – Joseph Larson Jul 16 '20 at 19:37
  • @Someprogrammerdude Even though this post has not gotten an answer, and it has been badly received, I think it is still important. I need to know the distinction to better understand this answer in another question on the site: https://stackoverflow.com/a/4756306/4416169 . A fully fledged answer instead of a comment would be appreciated. – Matias Chara Jul 17 '20 at 02:06
  • @JosephLarson I mean it does compile and its found in quite a few places if you search for it, namely the link in my first comment above. It also has a well-defined behaviour for simple cases as far as Im aware. – Matias Chara Jul 17 '20 at 02:12
  • Basically, calling `operator new` (or `operator new[]`) directly is like calling `malloc`: It allocates a certain amount of bytes or memory from the "heap", and returns a pointer to the first byte. The memory is not initialized in any way. – Some programmer dude Jul 17 '20 at 08:18
  • 1
    It is technically undefined behavior to assign to `dynamicInt[2]`, since no `int` object exists there. I don't know of cases where this is a problem in practice. – aschepler Jul 17 '20 at 11:23
  • @aschepler we would have to use placement new to create an int object in there(not using placement new array because its broken in this context and in general IMO)? obviously if so we would have to iterate and do placement new on each array element right? – Matias Chara Jul 17 '20 at 14:12
  • 1
    Correct. (Or use one of the `std::uninitialized_*` functions, but those all are specified to be equivalent to such loops with scalar placement new.) – aschepler Jul 17 '20 at 14:17
  • 1
    There's still the issue that pointer arithmetic, as in `dynamicInt[i]`, is undefined behavior on a pointer which is not pointing at an element in or past-the-end-of an existing array object. Though this also makes it harder to correctly use `std::uninitialized_*` algorithms. I think there are some known holes or shortcomings in the Standard around these questions. – aschepler Jul 17 '20 at 18:30

1 Answers1

1

There is no difference according to cppreference. The standard library just forwards operator new[] and operator delete[] to operator new and operator delete.

Mestkon
  • 3,532
  • 7
  • 18