Are there any compatible C ++ compilers that will be memory leaks for PODS derived from PODS?

Given:

#include <iostream>
using namespace std;

struct Concrete {
  char name[20];
  char quest[20];
  char favorite_color[13];
};

struct Concrete_with_knobs : public Concrete {
  int knobs[100000];
};

Concrete * cradle() {
    return new Concrete_with_knobs;
}

void grave(Concrete *p) {
    delete p;
}

void tomb_of_the_unknown_allocation(void *pv) {
    delete static_cast<int *>(pv);
}

void stress() {
    for (int i = 0; i < 1000000; ++i) {
        Concrete *p = cradle();
        grave(p);
    }
}

void extreme_stress() {
    for (int i = 0; i < 1000000; ++i) {
        Concrete *p = cradle();
        void *pv = p;
        tomb_of_the_unknown_allocation(pv);
    }
}

int main(int, char **) {
    cout << "sizeof(Concrete_with_knobs): " << sizeof(Concrete_with_knobs) << endl;
    cout << "Check your memory." << endl;
    char c;
    cin >> c;
    cout << "Stress." << endl;
    stress();
    cout << "Check your memory." << endl;
    cin >> c;
    cout << "Extreme stress." << endl;
    extreme_stress();
    cout << "Check your memory." << endl;
    cin >> c;
    return 0;
}

Summary:

  • The derived class (Concrete_with_knobs) is 400K more than its base class (Concrete).
  • cradle creates the Concrete_with_knobs object on the heap and returns its address as a Concrete pointer.
  • the grave takes the address as a Concrete pointer and performs the delete operation.
  • tomb_of_the_unknown_allocation accepts the address as void *, interprets it as an int address using static_cast, and performs the delete operation.
  • stress causes a cradle and grave a million times.
  • extreme_stress causes a cradle and tomb_of_the_unknown_allocation a million times.

++, extreme_stress? , , ?

+3
3

. (?) ++ operator new operator delete wrap malloc free , ​​, / (, , , , ). , operator new delete .

stress , , , , , .

, delete (int*) ++. . . , U.B. ISO ++ - , - , , U.B.

+3

++ , . , . .

++.

:

:

struct Base{
  int i;
};

struct Derived : public Base{
  int j;
};

- ++ :

// 1
Base* b1 = new Derived();
delete b1;
// 2
Base* b2 = new Derived();
void* vp = b2;
delete static_cast<int*>(vp);

? .

, . undefined. 5.3.5: 3, , , .

(Base) (Derived), .

.

, , ? . , , , , delete, , , new. .

. " ", , " - ?" undefined, , . , , , , . . , . - .

, , POD. POD, , .

+3

int, . POD , .

Another problem is whether the memory will be freed properly. I can not imagine an implementation where this would not be so, since the memory allocation functions underlying newand deletewill simply look like mallocand free, i.e. type-independent functions that work with pointers void *.

Pedantically, you invoke undefined behavior, but in fact I will eat a hat * if there is a compiler that cannot handle this.

* I do not have a hat.

+2
source

Source: https://habr.com/ru/post/1712263/


All Articles