2013-10-03 8 views
0

Итак, у меня проблема с домашним заданием, потому что getApple is const, я не могу установить locallyAllocated = false, что означает, что когда getApple вызывается с яблоком, созданным и освобождаемым в какой-либо другой программе, мой деструктор пытается освободить памяти и выбрасывает двойную свободную ошибку. Что я делаю неправильно, и как я могу это исправить? Примечание: функции, их параметры и подписи должны быть такими, какими они предназначены для нашего задания. Спасибо!Как узнать, когда освободить память?

class poop 
{ 

Apple localApple; 
bool locallyAllocated; 
void* pointer; 

public: 
    poop(const Apple &apple) 
    { 
     //Set our local apple to the apple in the provided address 
     localApple = apple; 
     locallyAllocated = false; 
    } 
    poop(string descr) 
    { 
     localApple.description = descr; 
     pointer = maloc(sizeof(localApple); 
     localApple.pointer = pointer 
     locallyAllocated = true; 
    } 
    ~poop() 
    { 
     if(locallyAllocated) 
     { 
       //This throws a double free error if "getApple" is ever called 
      free(pointer); 
     } 
    } 
    void getApple(Apple* apple) const 
    { 
     if(apple) 
     { 
      //Copies our local apple into the address of the given apple 
      //Because this function is "const", i can't do anything like set "locallyAllocated" to false 
      *apple = localApple 
     } 
    } 
} 
+6

Лучшее имя класса когда-либо! Кроме того, наименее ироничный комментарий когда-либо. – unwind

+0

Вы можете найти ключевое слово 'mutable'. – Angew

+0

Вы можете скопировать яблоко, если хотите освободить его память в другом классе.Но лучше избегать freeng-памяти вне класса, который выделил его – SpongeBobFan

ответ

0

У вас есть некоторые небезопасные вещи здесь происходит .. в частности:

poop(const Apple &apple) 
{ 
    //Set our local apple to the apple in the provided address 
    localApple = apple; 
    locallyAllocated = false; 
} 

Это означает, что кто-то, вероятно, может бесплатно apple.pointer из-под вас, что означает, что ваш localApple.pointer будет недействительным. Вы должны также выполнить выделение в этом методе и memcpy.

Однако здесь есть большая проблема ... вы даже не используете .pointer. Вам даже нужно что-то выделять? Какова ваша цель указателя?

Если вы довольны своим классом, как есть, вы должны проверить ключевое слово mutable.

0

Объявив locallyAllocatedmutable, вы сможете изменить его значение в методах const. Другим худшим решением было бы хранить locallyAllocated в качестве динамически распределенного логического.

+0

Благодарим вас, спасибо! Это эффективно решило проблему! Код по-прежнему бросает ошибку «malloc() повреждение памяти», но я подозреваю, что это связано с чем-то другим, с которым я столкнулся. Независимо от благодарности за вашу помощь! –

+0

@NateAnonymous: Не решайте проблемы с 'mutable'-hammer. Вы стреляете в ногу, и это начнет болеть, когда будет слишком поздно. – bitmask

+0

@bitmask: Игнорирование проблем с дизайном в целом, разве это не такая ситуация, когда вы будете использовать mutable? Вы хотите что-то изменить в классе, что вы не увидите видимого влияния вне класса. – Kindread

0

Мой первый инстинкт должен посоветовать вам использовать общие указатели

http://en.cppreference.com/w/cpp/memory/shared_ptr

Однако, если вам необходимо отслеживать при распределении самостоятельно, вы должны сделать locallyAllocated изменяемым. В условиях laymans это означает, что член может быть изменен даже в методе, обозначенном как const (он позволяет вам поддерживать логическую константу при нарушении «физического» const).

+1

[Не использовать cplusplus.com.] (Http://www.stackprinter.com/export?service=programmers.stackexchange&question=88241&printer=false&linktohome=true) – bitmask

+0

О, ничего себе. Ред. – Kindread

0

Для меня ваша проблема заключается в том, что несколько яблок должны иметь один и тот же объект, на который указывает Apple::pointer. Это, однако, не указано явно в вашем коде. Ошибка.

Существует не окончательное правило для управления памятью, которое подходит повсюду. Тем не менее, есть способы отразить ваше общее владение объекта, на который указывает Apple::pointer (Я предполагаю, что это яблоко тоже с учетом его размера?).

  • Одна вещь, которую вы можете сделать, это написать правильный конструктор копирования Apple::Apple(Apple const&), который позаботится о дублировании объекта, указанного в объекте.
  • Если вы хотите сохранить совместное владение, используйте std::shared_ptr вместо необработанного указателя. Это возьмет на себя ответственность за удаление указателя на объект с ваших плеч. «Последний, кто уйдет, закрывает дверь».

Обратите внимание, что ваш член locallyAllocated является очень упрощенной версией интеллектуальных указателей.

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