LINUX.ORG.RU

История изменений

Исправление quasimoto, (текущая версия) :

а вот здесь говорят нужно

Плохо говорят. Проблема может быть, если один объект содержит ссылки или указатели на другой или его части, тогда удаление второго делает первый невалидным до момента его собственного удаления, например:

#include <cstdio>

int main()
{
    int *x = new int(42);
    int **y = new int*[1];
    y[0] = x;
    printf("%d %d\n", x[0], *y[0]);
    delete x;
    printf("%d\n", *y[0]);
    // ==30938== Invalid read of size 4
    // ==30938==    at 0x40083A: main (in /tmp/a.out)
    // ==30938==  Address 0x59f9040 is 0 bytes inside a block of size 4 free'd
    // ==30938==    at 0x4C2AF3C: operator delete(void*) (vg_replace_malloc.c:480)
    // ==30938==    by 0x40082A: main (in /tmp/a.out)
    // ==30938== 
    delete[] y;
}

или

#include <cstdio>

struct A {
    int x;
    int y;
    struct AA {
        int x;
        int y;
    } xy;
};

struct B {
    int x;
    int y;
    A::AA &aa;
};

int main()
{
    A *a = new A{1, 2, {3, 4}};
    B *b = new B{5, 6, a->xy};
    printf("%d %d\n", a->x, b->aa.x);
    delete a;
    printf("%d\n", b->aa.x);
    delete b;
}

Но это никакой не «принцип кучи», то есть роль играет не порядок удаления относительно порядка создания, а то как устроен направленный граф описывающий как связаны ссылочно объекты, и тут нужно учитывать, что связь может быть на «обычную» часть или на часть со связью на ещё третий объект, во втором случае участники цикла второго типа в таком графе должны удаляться все вместе, а вообще удаление какого-то объекта делает невалидными все объекты выше по графу — все соседи независимо от типа связи и всё выше по связям второго типа. Из этого надо исходить, так что тебе должно быть видней как связаны (если вообще связаны) объекты vector<myclass*>.

З.Ы. «невалидным» значит, его использование _может_ привести к ошибкам времени выполнения, это не значит что его нельзя _как-то_ использовать не получая ошибок.

Исправление quasimoto, :

а вот здесь говорят нужно

Плохо говорят. Проблема может быть, если один объект содержит ссылки или указатели на другой или его части, тогда удаление второго делает первый невалидным до момента его собственного удаления, например:

#include <cstdio>

int main()
{
    int *x = new int(42);
    int **y = new int*[1];
    y[0] = x;
    printf("%d %d\n", x[0], *y[0]);
    delete x;
    printf("%d\n", *y[0]);
    // ==30938== Invalid read of size 4
    // ==30938==    at 0x40083A: main (in /tmp/a.out)
    // ==30938==  Address 0x59f9040 is 0 bytes inside a block of size 4 free'd
    // ==30938==    at 0x4C2AF3C: operator delete(void*) (vg_replace_malloc.c:480)
    // ==30938==    by 0x40082A: main (in /tmp/a.out)
    // ==30938== 
    delete[] y;
}

или

#include <cstdio>

struct A {
    int x;
    int y;
    struct AA {
        int x;
        int y;
    } xy;
};

struct B {
    int x;
    int y;
    A::AA &aa;
};

int main()
{
    A *a = new A{1, 2, {3, 4}};
    B *b = new B{5, 6, a->xy};
    printf("%d %d\n", a->x, b->aa.x);
    delete a;
    printf("%d\n", b->aa.x);
    delete b;
}

Но это никакой не «принцип кучи», то есть роль играет не порядок удаления относительно порядка создания, а то как устроен направленный граф описывающий как связаны ссылочно объекты, и тут нужно учитывать, что связь может быть на «обычную» часть или на часть со связью на ещё третий объект, во втором случае участники такого цикла в таком графе должны удаляться все вместе, а вообще удаление какого-то объекта делает невалидными все объекты выше по графу — все соседи независимо от типа связи и всё выше по связям второго типа. Из этого надо исходить, так что тебе должно быть видней как связаны (если вообще связаны) объекты vector<myclass*>.

Исходная версия quasimoto, :

а вот здесь говорят нужно

Плохо говорят. Проблема может быть, если один объект содержит ссылки или указатели на другой или его части, тогда удаление второго делает первый невалидным до момента его собственного удаления, например:

#include <cstdio>

int main()
{
    int *x = new int(42);
    int **y = new int*[1];
    y[0] = x;
    printf("%d %d\n", x[0], *y[0]);
    delete x;
    printf("%d\n", *y[0]);
    // ==30938== Invalid read of size 4
    // ==30938==    at 0x40083A: main (in /tmp/a.out)
    // ==30938==  Address 0x59f9040 is 0 bytes inside a block of size 4 free'd
    // ==30938==    at 0x4C2AF3C: operator delete(void*) (vg_replace_malloc.c:480)
    // ==30938==    by 0x40082A: main (in /tmp/a.out)
    // ==30938== 
    delete[] y;
}

Но это никакой не «принцип кучи», то есть роль играет не порядок удаления относительно порядка создания, а то как устроен направленный граф описывающий как связаны ссылочно объекты, и тут нужно учитывать, что связь может быть на «обычную» часть или на часть со связью на ещё третий объект, во втором случае участники такого цикла в таком графе должны удаляться все вместе, а вообще удаление какого-то объекта делает невалидными все объекты выше по графу — все соседи независимо от типа связи и всё выше по связям второго типа. Из этого надо исходить, так что тебе должно быть видней как связаны (если вообще связаны) объекты vector<myclass*>.