Проблема с использованием оператора удаления для массива объектов, размещенных в куче, с использованием цикла FOR вместо использования ключевого слова delete[] array_of_objects

#include <iostream>

class ArrayClass
{
private:
    int *m_Arr;
    int i;

public:
    int Size;
    ArrayClass() : Size(5), i(0), m_Arr(nullptr)
    {
        std::cout << "The constructor was called." << std::endl;
    }
    ~ArrayClass()
    {
        std::cout << "The destructor was called." << std::endl;
        delete[] m_Arr;
    }
    void InitArr()
    {
        m_Arr = new int[Size];
    }
    void Setter(int &var)
    {
        *(m_Arr + i) = var;
        i++;
    }
    int *Getter() const
    {
        return m_Arr;
    }
};

int main()
{
    ArrayClass *instance = new ArrayClass[2];
    std::cout << instance << std::endl;
    for (int j = 0; j < 2; j++)
    {
        (instance + j)->InitArr();
        for (int i = 1; i <= (instance + j)->Size; i++)
        {
            (instance + j)->Setter(i);
        }
        int *Get = (instance + j)->Getter();
        std::cout << "The numbers are:" << std::endl;
        for (int i = 0; i < (instance + j)->Size; i++)
        {
            std::cout << *(Get + i) << std::endl;
        }
    }
    for (int l = 0; l < 2; l++)
    {
        delete (instance + l);
    }
    std::cin.get();
    return 0;
}

Я новичок в C++ и столкнулся с проблемой: я пытаюсь использовать ключевое слово delete, используя цикл for, вместо экземпляра delete[]. Я просто пытаюсь сохранить этот метод удаления массива экземпляров в куче, используя арифметику указателей. Но удаление не выполняет свою работу, когда я запускаю программу, фрагмент кода деструктора не распечатывается в cmd, программа просто завершает работу, не соблюдая строку std::cin.get();

Только это работает. delete[] instance;.
Но я хочу, чтобы этот метод использовался,

for (int l = 0; l < 2; l++)
    {
        delete (instance + l);
    }

Итак, не могли бы вы исправить ошибку.
Или метод, который я пытаюсь использовать, действителен даже на C++?

Каждый delete должен соответствовать new, который использовался для выделения памяти. У вас есть один new[], который нужно создать instance, но затем попробуйте вызвать 3 delete, чтобы удалить его — это не сработает. delete[] instance вне любого цикла — единственный разрешенный способ освободить instance.

Yksisarvinen 09.07.2024 14:11

вам необходимо прочитать о правиле 3/5, чтобы понять следующие проблемы, с которыми вы столкнетесь

463035818_is_not_an_ai 09.07.2024 14:17

Вы не хотите использовать этот метод, потому что он неправильный. Купите себе хорошую книгу и перестаньте гадать.

molbdnilo 09.07.2024 14:18

«Только это работает. delete[] instance;». потому что только это правильный способ удалить массив. Больше ничего особенного (кроме того, что вам вообще не следует использовать new и delete, но я полагаю, это для упражнения)

463035818_is_not_an_ai 09.07.2024 14:19

Кроме того, с указателями (и массивами) *(m_Arr + i) работает точно так же, как m_arr[i].

BoP 09.07.2024 14:19

Я голосую за закрытие этого вопроса, потому что ОП, похоже, знает, что не так, а что правильно, но хочет ошибаться.

463035818_is_not_an_ai 09.07.2024 14:20

@ 463035818_is_not_an_ai, я думаю, автор вопроса просто хочет знать, почему его/ее метод не работает. Так ли плохо быть любопытным?

Ilia Nechaev 09.07.2024 15:35

«Я новичок в C++ и столкнулся с проблемой: я пытаюсь использовать ключевое слово delete». Это ваша проблема. new и delete — тема для продвинутых. Если кто-то претендует научить вас C++ и начинает с владения необработанными указателями, он оказывает вам медвежью услугу.

Caleth 09.07.2024 15:43

@SPGC Я никого не сужу. Тем более не из-за любопытства. Вопрос можно было бы сформулировать лучше. И когда я замечаю это, я упоминаю об этом. Судите меня за это :П

463035818_is_not_an_ai 09.07.2024 15:47

@ 463035818_is_not_an_ai, нет, я не буду этого делать) только зачем закрывать вопрос до того, как на него будет получен ответ, даже если вопрос плохо сформулирован?

Ilia Nechaev 09.07.2024 15:50

@SPGC, потому что мы пытаемся сделать SO местом с хорошими вопросами и хорошими ответами. Заключительные вопросы – не оскорбление, а необходимость

463035818_is_not_an_ai 09.07.2024 15:51

@463035818_is_not_an_ai, ну ИМХО, именно поэтому новички предпочитают использовать чатgpt или copilot, там они получат ответ (в основном говно, но обычно их это устраивает), здесь они обычно получают много комментариев по поводу "плохая структура, нет выходов" и т. д.» и нет ответа...

Ilia Nechaev 09.07.2024 15:55

@SPGC, они получили ответ, нет?

463035818_is_not_an_ai 09.07.2024 16:17

@ 463035818_is_not_an_ai, да, но не всегда они это понимают, и закрытие вопросов с ИМХО, возможно, плохой формулировкой без ответов, здесь является обычной практикой. Это моя точка зрения

Ilia Nechaev 09.07.2024 16:18

Давайте продолжим обсуждение в чате.

Ilia Nechaev 09.07.2024 18:36
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
15
72
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

К сожалению, метод, который вы хотите использовать, недопустим в C++.

Вам нужно использовать delete, чтобы освободить память для объекта, созданного с помощью new, и delete[], чтобы освободить память для массива, созданного с помощью new[]. Простая мнемоника - для каждого new один delete, для каждого new[] один delete[].

Причина этого в том, что когда вы создаете что-то с помощью new или new[], вы выделяете немного больше памяти, чем ожидаете, дополнительная память выделяется для технической информации для оператора delete или delete[]. Эта информация указывает объем памяти, который был выделен и который должен быть позже удален с помощью оператора delete или delete[]. А когда вы используете delete для каждого элемента массива, выделенного с помощью new[], оператор delete ищет техническую информацию не в том месте, и это может привести к неопределенному поведению.

Это простое объяснение, для более точного советую вам посмотреть на cppreference.com, но для начала я считаю, что этого объяснения достаточно.

Другие вопросы по теме