2

I found that such code

#include <iostream>

class A
{
public:
    A()
    {
        std::cout << "cA" << std::endl;
    }
    virtual ~A()
    {
        std::cout << "dA" << std::endl;
    }
    char a[11];
};
class B : public A
{
public:
    B()
    {
        std::cout << "cB" << std::endl;
    }
    ~B()
    {
        std::cout << "dB" << std::endl;
    }
    char a[21];
};
int main()
{
    {
        A* aa  = new B[5];
        std::cout << "==============" << std::endl;
        delete[] aa;
    }
    return 0;
}

works perfectly well in VC++ compiler, but fail when complied by GCC. I understand why using arrays like this could be bad idea (thanks Meyers) but how is it works in VC++? Is it store size of real object before array?

brachistochron
  • 321
  • 1
  • 11
  • 2
    What actually happens in the gcc case? – Bathsheba Mar 10 '16 at 08:21
  • Undefined behavior if undefined. At least if I understand this cppreference entry correctly. http://en.cppreference.com/w/cpp/language/delete – StoryTeller - Unslander Monica Mar 10 '16 at 08:26
  • I getting segmentation fault. You could see here http://ideone.com/rBZYZd – brachistochron Mar 10 '16 at 08:27
  • I'm not confident this *is* UB. Good question, plus one. – Bathsheba Mar 10 '16 at 08:35
  • 1
    You're invoking *undefined behavior*. Per `[expr.delete]` § 5.3.5/3, "In the second alternative (delete array) if the dynamic type of the object to be deleted differs from its static type, the behavior is undefined." The static type of your pointer is `A`, of the dynamic object is `B`. This differs from the non-array `delete` operator, where wiring up a virtual destructor becomes relevant, but is none-the-less supported. – WhozCraig Mar 10 '16 at 08:37
  • @StoryTeller there is more intresting example http://ideone.com/SAuQq2. It seems, that delete[] somehow knows real offsets to call appropriate destructor from vtbl. Still works perfectly with VC++ – brachistochron Mar 10 '16 at 08:37
  • @WhozCraig: come on you should post this as an answer. You are right. OP's code invokes __undefined behaviour__ . – Destructor Mar 10 '16 at 10:09
  • Possible duplicate of [Why is it undefined behavior to delete\[\] an array of derived objects via a base pointer?](http://stackoverflow.com/questions/6171814/why-is-it-undefined-behavior-to-delete-an-array-of-derived-objects-via-a-base) – Destructor Mar 10 '16 at 10:10
  • @Destructor The question was "how it works in VC++". Too much coincedence for undefined behaviour. – brachistochron Mar 10 '16 at 10:24
  • I found, that it works even if RTTI disabled. So, it seems that some additional data stored in pointer header. – brachistochron Mar 10 '16 at 10:26
  • @brachistochron: undefined behaviour means anything can happen. It is also possible that program may continue to run without any error silently when compiled using one compiler but crashes on another compiler. The behaviour is completely undefined in this case. So, the behavior of program varies on compilers, platforms or even under different compiler optimizations. – Destructor Mar 10 '16 at 10:33
  • 1
    To iterate the array (see `vector deleting destructor`), and call the right destructor, the compiler needs to know the size of the actual object. In the case above this can be found at compile time. I personally, prefer VC's behavior: it is in line with what one expects. – zdf Mar 10 '16 at 11:05

0 Answers0