2012-03-13 115 views
0

考虑下面的代码片段谁负责释放分配的内存?

void xyz(CString **mapping) 
{ 
    *mappings = new CString[10]; 
    (*mappings)[0] = "hello"; 
    //... 
} 

void main(int argc, char **argv) 
{ 
    CString *tmp; 
    xyz(&tmp); 
    // now we have the CString array defined in xyz 
} 

我想要做的是,以填补因主峰的VAR与由另一个函数生成一些值。我读了它的最佳做法,即删除/释放与分配的功能相同的功能。这在这种情况下是不可能的,因为xyz存在的唯一原因是生成数据(这仅仅是一个例子,在实际情况下,在xyz ;中会有更多复杂性))。我也考虑在main中的堆栈上创建一个数组,并将它传递给函数,但在我的情况下,数组的大小在当时不是固定的(它在xyz中确定)。清理分配内存的最干净和最常用的方法是什么? 如果我们有方法xyz的对象,那么最佳实践是什么?要创建另一个方法(例如freeMapping()),在处理数据后必须由调用方调用?

+4

C或C++,决定。因为在C++中,你只需使用'std :: vector'。 – 2012-03-13 23:04:05

+3

如果您正在研究C++,那么将分配的数据包装到一个对象中,该对象在超出范围时释放内存。 – Tony 2012-03-13 23:04:09

+0

上次编辑将问题从C++改为C,这会使答案失效。如果您有新问题,请在网站上进行搜索,如果失败(不会),请提出新问题。 – 2015-05-11 18:29:07

回答

0

这是你在这里展示的不良做法。所以它有2个解决方案:

  1. 在主函数中分配和释放内存。

  2. 创建一个类,它将负责该字符串的所有操作并在主函数中使用它。

0

的RAII风格类(即释放的对象在其析构函数的包装)是处理这种事情的常用方法(见的std :: auto_ptr的或一些更现代的替代品,如boost ::的scoped_ptr或std :: unique_ptr)。当auto_ptr/unique_ptr超出范围时,会自动调用delete。

传入对调用程序堆栈上创建的std :: vector的引用可能有效。

通过值返回一个std :: vector很容易理解,并且可以根据您的要求很好地执行。

+0

RAII不仅仅是一个包装资源的资源,它可以释放dtor中的资源。智能指针也不是独立于RAII的;他们使用RAII来实现拥有不同所有权语义的指针。 – bames53 2012-03-14 00:21:50

1

有许多不同的方案,人们使用多年来,有些更好或更糟。良好的策略定义了一个严格一致的模式,为资源的“所有权”制定了规则,即清理责任和确保没有任何资源非法访问资源。成功策略的规则也是这样的,只有对资源的本地视图以及如何使用才是安全访问资源的必要条件。

您应该在现代C++中使用的策略称为RAII或“资源获取是初始化”。这个名字意味着任何获得的资源都应该是一个初始化。例如:

std::string s = "Hello, World"; 

此代码获取一些内存作为存储字符串数据的资源,但您看到的只是该字符串已初始化。被初始化的对象拥有内存。这意味着它负责管理内存的使用期限并限制对内存的访问。使用该对象的代码根本不需要考虑资源。只需确保它正确使用对象本身,并且隐藏资源的生命周期将依次正确管理。

使用RAII不仅方便了本地资源的正常管理,而且在出现异常情况下也大大简化了资源的正确清理工作。当范围由于异常而退出时,C++保证销毁该范围内的所有完全构造的对象。如果清理资源的必要任务是由对象析构函数完成的,那么资源不会泄漏,并且不需要将明确的异常处理添加到使用资源的每个范围。

C++已经包含了许多类型资源的资源拥有类。对于动态调整大小的阵列使用std::vector

std::vector<CString> xyz() 
{ 
    // C++11 
    return {"hello",...}; 

    // or C++03 
    std::vector<CString> mappings; 
    mappings.push_back("hello"); 
    ... 
    return mappings 
} 

void main(int argc, char **argv) 
{ 
    std::vector<CString> tmp = xyz(); 
    // now we have the CString array defined in xyz 
    // the array gets automatically cleaned up by std::vector's destructor 
}