2010-07-30 181 views
2

这是一个关于C++代码的内存管理问题。内存管理

using namespace std; 
#include <iostream> 
#include <string.h> 

int main() 
{ 
string a="first"; 
string *b= new string; 
*b=a; 
a="second"; 
cout << *b << ", " << a; 
delete b; 
return 0; 
} 

我们可以取消分配存储b指向的字符串的内存块。 我假设这意味着b完成后不再有任何意义。 我们可以释放b来释放一些内存。为什么我们不能释放一个? 我知道我们只能删除/释放指针,但字符串a必须占用一些内存。 有什么方法可以释放字符串a占用的内存? 如果有足够的字符串以与a初始化相同的方式初始化,那么内存用完了吗?

回答

0

分配给a的内存将在函数返回后自动释放。

4

字符串a在堆栈中声明。您不能手动释放它,但一旦它离开作用域时它将自动释放(例如,当封闭函数返回时)。如果您需要释放内存中间函数,请动态声明它(如同您为b所做的那样)。

+0

+1你的答案比我的更完整。 – karlphillip 2010-07-30 16:33:05

+0

或者您可以将字符串放在较小的范围内......并不是在大多数情况下都是值得的。 – 2010-07-30 17:08:06

2

自动对象(如您的a)在外出时会被销毁。见下面的例子:

int main() 
    { 

    { 
    string a="first"; 
    string *b= new string; 
    *b=a; 
    a="second"; 
    cout << *b << ", " << a; 
    delete b; //b gets freed 
    } //a gets freed because it has gone out of scope 
/* You can write more code here that does not need a */ 
return 0; 

}

0

a这里是自动分配的“堆栈”,并会自动销毁/释放时,它超出范围。

当您使用动态内存与new/malloc时,它被分配到“堆”,这只是程序可用的一堆内存。你必须手动管理这个,程序不知道什么时候摆脱它。

如果你真的在这种情况下担心内存,你应该只使用动态内存分配。

编辑:这给了比我想说的更完整的解释: http://en.wikipedia.org/wiki/Malloc#Rationale

3

字符串由包含指向存储的字符串数据的小物件,它的寿命是由管理的目的。通常不需要担心对象自身占用的内存,但是如果字符串很大,则可能需要释放存储空间而不破坏对象。

调用clear()或从emptry字符串进行赋值可能不会释放存储空间。确保它被释放的方法是将字符串与新构建的临时对象交换;临时的析构函数将释放它。

string().swap(a); // replaces `a` with an empty string 

您也可以对任何标准容器执行此操作。

3

这很尴尬。

<string.h>是C标头。它没有定义string。它看起来像你的版本<iostream>直接或间接包括<string>,否则会出现错误。

字符串(由成对引号分隔的那些东西)可能在任何地方,包括只读内存段。 (他们确实占用了内存,但是你必须有很多文本才能产生重大影响:类似战争与和平不会占用完整的大小。)在这种情况下,std::string是用该值进行初始化,然后再赋值给它。 std::string处理它使用的内存。

在C++中,几乎没有理由指向std::stringstd::string没有内容就占用太多空间,并且管理内容本身的内存。你是否与char *混淆?

new一个为bstd::string,然后再指定地址b没有delete荷兰国际集团的内存。这是内存泄漏。你为bnew仍然分配在那里,但它没有办法delete它,所以它会占用内存的程序期间。

然后,一旦您将a的地址分配给b,您delete b;。这是一个糟糕的想法,并可能以一种可能无法预测的方式搞砸重要事情。只有您用new获得的delete内存。 (这里delete ing的重要不是b是一个指针,应该删除,但它指向的内存不是通过new得到的。)

内存管理的工作原理与此类似。字符串文字被分配到某处。所有你知道的是,你不应该试图改变它或以任何方式它delete它。使用该值,不要碰其余的。 A std::string为其内容管理内存,并在其析构函数中处理该内存。一个在函数或其他块中声明的变量一旦超出范围就会被销毁(尽管它可能指向的内容不会被自动销毁;只有当它是一个智能指针或管理自己的内存或其他内容时)。如果你的内存是new,请不要丢弃指针值,直到它为delete d。如果您还没有new ed内存,请不要delete它。

+0

+1代码的详细说明。 – rturrado 2010-08-01 18:03:37

+0

嗯,实际上这里没有内存泄漏:作者写过 'string * b = new string; * b = a; ' 如果他写道: ' string * b = new string; b =&a; ' 虽然同意你的其他言论。 – Haspemulator 2010-08-05 03:35:11

+0

+1提到字符串文字内存位置。它们通常驻留在应用程序的静态内存中,而不是堆栈或堆中。这就是为什么你不应该删除一个字符串文字的指针。 – Zoomulator 2012-01-17 20:06:42