2009-12-10 4 views
9

Это нормально (и правовой), чтобы удалить указатель, который был принят в качестве аргумента функции, такие как это:Использование удаления указателей, передаваемых в качестве аргументов функции

#include<iostream> 

class test_class{ 
public: 
    test_class():h(9){} 
    int h; 
    ~test_class(){std::cout<<"deleted";} 
}; 

void delete_test(test_class* pointer_2){ 
    delete pointer_2; 
} 

int main(){ 
    test_class* pointer_1; 

    while(true){ 
     pointer_1 = new test_class; 

     //std::cout<<pointer_1->h; 

     delete_test(pointer_1); 
    } 
} 

Теперь компилируется нормально, но я просто хочу чтобы убедиться, что это всегда будет так.

ответ

11

Он всегда будет компилироваться без ошибок.

Хорошо, что передать указатель на функцию и удалить ее в этой функции является потенциально другой историей, в зависимости от специфики вашей программы.

Основная идея, которую вы должны учесть, - это «владение» заостренными данными. Когда вы передаете этот указатель, имеет ли вызывающая функция право собственности на передаваемые данные? то есть это единственное место, на которое можно ссылаться на этих данных? Вы отказываетесь от права собственности на данные с привязкой к данным, без каких-либо шансов, что вызывающая функция снова будет ссылаться на данные? Если да, то вы должны удалить его.

Если вызывающая функция может ссылаться на данные снова, вы не должны ее удалять.

Если есть другие ссылки на данные через различные структуры данных, тогда небезопасно удалять эти данные, если у вас нет какой-либо дисциплины в вашем коде, чтобы вы никогда не ссылались на данные снова из этих мест. Это трудно сделать и является источником многих ошибок программирования.

C++ tr1 shared_ptr < > - это умный указатель, который помогает в таких ситуациях - он управляет этой концепцией собственности, сохраняя счетчик ссылок, который отслеживает количество ссылок на данные. Если счетчик ссылок равен 1, то есть 1 ясный владелец. Если счетчик ссылок больше 1, тогда совместное использование собственности. Если счетчик ссылок равен 0, то больше нет ссылок на данные, а shared_ptr < > удалит его, когда вызывается деструктор shared_ptr < >.

+0

То, что я всегда удивляю, заключается в том, что удаление указателя является законным, даже если оно 'const'. –

2

Да, это совершенно законно. Вы можете указать delete указатель откуда угодно, если он указывает на некоторый объект, выделенный на кучу (или равен 0).

Независимо от того, ожидает ли вызывающий объект их объект функцией, это другой вопрос.

7

Да, это действительно.

Обычно это делается на C (с malloc и бесплатным вместо нового и удалять, очевидно). В C++ обычно предпочтительнее использовать другие идиомы управления памятью, например RAII.

6

Да, это законно на C++, но это обычно не считается хорошей практикой. Это всегда лучше для класса, который выполнял new до delete.

+0

Я не вижу класс, «выполняющий новый» в любом месте данного кода. Вероятно, вы подразумевали «block» вместо «class», но это не всегда возможно или полезно. –

+0

Но этот класс вполне может выполнить удаление с помощью функции, которая принимает указатель в качестве параметра. – 2009-12-10 15:30:23

0

Это совершенно законно для этого. Вы должны убедиться, что указатель не используется в вызывающем абоненте после этой точки. В общем, имя функции, выполняющей удаление, должно указывать на то, что происходит (например, содержать delete, release, free и т. Д.). Другая потенциальная проблема заключается в том, чтобы удостовериться, что указанные данные были выделены новым, а не новым [].

1

Это совершенно законно, хотя в таком случае, вероятно, лучше управлять владением памятью с чем-то вроде boost::shared_ptr.

0

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

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

Если у вас есть указатели, вы должны проверить, чтобы убедиться, что они не равны нулю, чтобы избежать какого-либо неопределенного поведения.

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