-1

If delete[] "knows" the size of any dynamically allocated array, shouldn't I be able to query its size somehow?

This is from cplusplus.com mixed with some of my own code to show what I mean:

// operator delete[] example
#include <iostream>     // std::cout

struct MyClass {
  MyClass() {std::cout <<"MyClass constructed\n";}
  ~MyClass() {std::cout <<"MyClass destroyed\n";}
};

int main () {
  MyClass * pt;
  MyClass * foo;
  MyClass * bar;

  pt = new MyClass[3];
  delete[] pt;      
  foo = new MyClass[12];
  delete[] &foo[0]; // this works      
  bar = new MyClass[33];
  delete[] &bar[1]; // this does not work

  return 0;
}

Motivation: If the first element of the array is special than any for-all would need only the last pointer and decrement until the first is detected... (I guess it could be "found" by looking for delete[] exception/error)

Andreas
  • 5,086
  • 3
  • 16
  • 36
  • 1
    Possible duplicate of [How does delete\[\] "know" the size of the operand array?](https://stackoverflow.com/questions/197675/how-does-delete-know-the-size-of-the-operand-array) – PythEch Dec 13 '17 at 19:56
  • 1
    Where do you initialize foo and bar? The second example you show should not work, as foo was never declared. This does not compile. – user3483203 Dec 13 '17 at 19:56
  • 1
    Although this is a rather popular demand, the answer is, unfortunately, "no". – Sergey Kalinichenko Dec 13 '17 at 19:56
  • You're asking two question. The one in your question's title and in the first sentence of the question. Which question do you want answered here? – François Andrieux Dec 13 '17 at 19:56
  • If you read the information about the tags, you would see that `dynamic-arrays` is specifically about array like constructs that can change size dynamically at runtime (and not dynamically allocated arrays). – crashmstr Dec 13 '17 at 19:56
  • 1
    `&foo[0]`, `foo` and `&0[foo]` are equivalent to `foo + 0`. In this case you are releasing memory using pointer to the front of memory block. With `delete[] &bar[1];` you are trying to release memory by pointer which is set to middle of allocated memory block. Standard library threats this as a fatal error of heap corruption. – Marek R Dec 13 '17 at 20:06
  • 1
    Use `std::vector`. – n. m. could be an AI Dec 13 '17 at 20:07
  • @chris added declaration of foo and bar – Andreas Dec 17 '17 at 10:54

1 Answers1

2

Your approach - though being quite creative :-) - does not work. The reason is that you cannot "try out" delete; you rather have to make sure that the pointer passed to delete is one that has previously been obtained by new. Otherwise, the behaviour is undefined (cf, for example, this definition of delete at cppreference.com):

If the pointer passed to the standard library deallocation function was not obtained from the corresponding standard library allocation function, the behavior is undefined.

So any try that has not been "the first pointer" (i.e. the beginning of the array) will yield undefined behaviour (a crash, something obscure, even nothing) and you must not rely on such a "behaviour".

Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58
  • `MyClass *pt1 = new MyClass[3]; MyClass *pt2 = &pt1[0]; std::cout << std::boolalpha << (pt1 == pt2);` Techically `pt2` was not obtained from the corresponding standard library allocation function, yet it is the same pointer as `pt1` that was obtained from the corresponding standard library allocation function. It this still UB? – Killzone Kid Dec 13 '17 at 20:20
  • @KillzoneKid -- by that analysis, `pt1` was not obtained from the standard library allocation function. It's value is a **copy** of the pointer that the allocation function returned. So is `pt2`. Choose your poison: either nothing works because of a hyper-technical (and unwarranted) reading of the requirement, or both of them work. – Pete Becker Dec 13 '17 at 20:36
  • @KillzoneKid: What is important is that the memory address you pass to `delete` must be the same address that `new` returned. How you determine the address before passing it to `delete` does not matter. `pt1`, `&pt1[0]`, `pt1+0`, `pt1+1-1`, they all point to the same address. – Remy Lebeau Dec 13 '17 at 20:36
  • @RemyLebeau This is what I thought and what makes sense. Just wanted to make sure cppreference formulation is not final. – Killzone Kid Dec 13 '17 at 21:02