0

I have the following code. It calls the class's destructor indefinitely and crashes. If I change the size of the array to something larger than 0 is works fine.

#include <iostream>

using namespace std;

class ClassA {

    public:
        ClassA() {

            cout << "constructor" << endl;
        }
        ~ClassA() {

            cout << "destructor" << endl;
        }
};

int main() {

    ClassA *ptr;

    cout << (void*) ptr << endl;

    ptr = new ClassA[0];

    cout << (void*) ptr << endl;

    delete[] ptr;

    cin.get();

    return 0;
}
  • 1
    If it works with an array size > 0, then what's the problem? – foo64 Apr 11 '13 at 21:30
  • 4
    Details here: http://stackoverflow.com/questions/1087042/c-new-int0-will-it-allocate-memory a zero-sized array is somewhat undefined behavior, and you should not use pointers to it, except to delete. – Marc B Apr 11 '13 at 21:30
  • It runs ok here http://liveworkspace.org/code/2xF98s$0 – taocp Apr 11 '13 at 21:30
  • 3
    @tacp Ya but it is undefined behavior. It might work sometime with some compiler. It might not another time. –  Apr 11 '13 at 21:31
  • @tacp That's what happens when you play with undefined behavior. One compiler generates working code while others may not. – Captain Obvlious Apr 11 '13 at 21:33
  • http://stackoverflow.com/questions/9722632/what-happens-if-i-define-a-0-size-array-in-c-c –  Apr 11 '13 at 21:33
  • @stardust_ ,CaptainObvlious thanks! – taocp Apr 11 '13 at 21:33
  • @stardust_ it does not allow me to @ two persons, that's why..... – taocp Apr 11 '13 at 21:41
  • @Marc B Can you please explain what you mean by delete. In my code I am trying to delete the zero-sized array and it fails. – Ivan Georgiev Apr 11 '13 at 21:45
  • @CaptainObvlious, it is a bit more complicated. The compiler is allowed to assume you _never_ do anything that is undefined behaviour, so it can generate whatever code it likes as long as it works right for defined behaviour. If the code generated works "right" in such a corner case (for whatever value of "right" you want) is anybody's guess. Change code elsewere, get a new version of the compiler, give other flags, and all bets are off. By definition, _anything_ that happens in such a case is "working as designed". One ancient gcc started the game nethack when confronted with some such cases. – vonbrand Apr 11 '13 at 21:49
  • @tacp I am very sorry man. I thought you were telling me I am stating the obvious. Apologies man. But in my defense his name is confusing. –  Apr 11 '13 at 21:52

1 Answers1

0

The C++ standard states in §8.3.4 that arrays are declared in the form

D1 [ constant-expression ] attribute-specifier-seq

...If the constant-expression (5.19) is present, it shall be an integral constant expression and its value shall be greater than zero.

In other words, they can't be size 0. Compilers allow you to do so anyways for programming practices outlined here (which you arguably shouldn't do).

When you break rules like this, whatever happens next is undefined behavior - the compiler can do whatever it wants. The reason for this is to give the compiler writers some leeway with how they code the compiler, and also allow for some optimizations.

Matt Kline
  • 10,149
  • 7
  • 50
  • 87