2016-02-17 10 views
-4

У меня есть код C++. Так как память динамически распределена, она должна быть выделена в кучу. Или, поскольку память была выделена прямо во время объявления, а не в каком-либо конструкторе, выделяется ли она на стек? И нужен ли мне де-конструктор для освобождения памяти?Где выделена эта память - куча или стек?

class param{ 
public: 
    char* st = new char[256]; 
}; 

Что происходит в следующем сценарии? Я предполагаю, что это выделено на стек, и его не нужно освобождать с помощью деконструктора.

class param{ 
public: 
    char st[256]; 
}; 

Третий способ написать это как:

class param{ 
public: 
    char* st; 
    param() 
    { 
     st = new char[256]; 
    } 

    ~param() 
    { 
     delete[] st; 
    } 
}; 

Какой из этих трех правильный способ сделать это?

+0

Запуск первой версии против valgrind указывает на утечку памяти, поэтому она выделяется в куче. Вам нужно будет удалить это место вручную позже, и это будет довольно слабым. Правильный способ - это либо второй, либо третий способ. Для третьего способа убедитесь, что вы предоставили подходящую (или удалили) копию и переместили конструкторы и операторы присваивания, чтобы обеспечить правильное обращение с памятью. –

+3

На самом деле ни один из них не имеет никакого смысла. Используйте 'std :: vector' или' std :: array'. –

ответ

2

так как память была выделена в момент объявления, а не в каком-либо конструкторе, выделяется ли она на стек?

Нет, он по-прежнему динамически распределяется.

И нужен ли мне де-конструктор для освобождения памяти?

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

Другие предложения:

  1. Подумайте об использовании std::vector или std::array, так как это C++.

  2. Для 3-й случай, пожалуйста, обратитесь к What is The Rule of Three? и Rule-of-Three becomes Rule-of-Five with C++11?

+2

3-й случай - неточно: он не соответствует правилу 3/5/0. – emlai

+0

@zenith Специфично для вопроса OP, и по сравнению с 1-м случаем, все должно быть хорошо. Во всяком случае, я удалил его, так как это неверно. – songyuanyao

1

new всегда выделяется в куче.

В первом примере указатель от new помещается в член класса.

Экземпляр этого класса может быть создан в стеке; или экземпляр класса может быть создан на самой куче, через new. Независимо от того, каким образом экземпляр класса получает экземпляр сам, будь то в куче или в стеке, его член st всегда будет указывать на выделенную кучу память.

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

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

Но, возможно, возникнет какая-то эзотерическая ситуация, когда даже первый пример верен.

+1

Нет такой вещи, как _the heap_ в правильной терминологии в соответствии со стандартом C++. –

Смежные вопросы