正确释放内存的问题

时间:2014-05-04 12:52:14

标签: c++ memory-management

您好我正在尝试为此字符指针释放内存但因为它被初始化为名称我无法删除/释放它。我该如何处理这种情况?我的头文件和实现文件如下所示。

/// Header file.

#ifndef __DAY_H__
#define __DAY_H__


class day {
    private:
        char* name;
        int   nClasses;
        bool  status; //working day or a holiday

    public:
        day();
        day( char * name, int place, bool status);
        day( const day& );
        //operator=( const day& );
        ~day();

        char * getName () const;
        int    getClasses () const;
        bool   getStatus () const;

        void setName ( char * name );
        void setClasses ( int classes );
        void setStatus ( bool status );
};


#endif


/// .cpp file
#include <iostream>
#include "day.hpp"
#include <string.h>

day::day()
{
    name = new char[10];
    name = "Monday";
    nClasses = 1;
    status = true;
}

day::day(char * _name, int _classes, bool _status)
{
    name = new char[10];
    strncpy(name, _name, 10);
    nClasses = _classes;
    status = _status;
}

day::day(const day& _myday)
{
    name = new char[10];
    name = _myday.name;
    nClasses = _myday.nClasses;
    status = _myday.status;
}

char*
day::getName() const
{
    return name;
}

int
day::getClasses() const
{
    return nClasses;
}

bool
day::getStatus() const
{
    return status;
}

void
day::setName( char * _name )
{
    name = _name;
}

void
day::setClasses( int _classes )
{
    nClasses = _classes;
}

void
day::setStatus( bool _status )
{
    status = _status;
}

day::~day()
{
    if (name != 0 ) {
        std::cout << "Deleting name" << std::endl;
        delete name;
    }
}

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

如果这不是一项家庭作业,请停在那里,用char*替换std::string,并解决您的问题。

(另外你可以删除你的析构函数和复制构造函数,编译器生成的构造函数就足够了。)


如果这是手动内存管理的练习,那么您需要修复几个方面。

你有两个地方的这种模式:

char *var = new char[N];
var = something_else;

这是内存泄漏。指针new给你在第二个语句中被其他东西替换。你没有另一个指向新分配区块的指针,所以它已经泄露了。

更重要的是,默认构造函数中的第二个赋值形式为:

var = "string literal";

您不允许删除字符串文字,它具有程序的生命周期。所以你最终会出现你已经泄露内存的情况,你无法告诉你是否必须删除你的析构函数。

要解决此问题,您必须进行分配(如有必要),然后从您获得的任何来源进行复制。这样做的好处是不会存储您直接传递的指针,如果调用者决定自己释放它,则会导致其他错误。因此,即使源是字符串文字:

var = new char[N];
strncpy(var, source, N);
var[N-1] = 0; // check the docs for strncpy very carefully

一旦你解决了这个问题,你就需要遵守Rule of Three,你确实需要一个复制赋值运算符。它需要妥善处理自我分配。

然后你必须修复你的析构函数。您使用name分配new[]。您必须取消分配delete[]。这两个牵手。 (对name != 0进行测试是不必要的,deletedelete[]很好地处理空值 - 即在传递空指针时它们什么也不做。)

这也是了解std::shared_ptrstd::unique_ptr的好时机。在大多数情况下,应避免使用普通newdelete