2013-04-09 69 views
-2

我有一点麻烦的理解是我得到的输出的矢量奇怪的行为,当我运行这个简单的代码与指针

#include <vector> 
#include <iostream> 
#include "LxUNIXsys.h" 
using namespace std; 

int main(int argc, char** argv) { 

    //memory management class 
    LxUNIXsys mem_manager; 

    vector <double*> vec; 

    mem_manager.DumpMemoryInfo();getchar(); 
    for(int i =0; i < 3; i++) vec.push_back(new double (3)); 
    for(int i =0; i < vec.size(); i++) cout << *vec[i] << endl; 
    mem_manager.DumpMemoryInfo();getchar(); 
    for(int i =0; i < vec.size(); i++) delete vec[i]; 
    vec.clear(); 
    for(int i =0; i < 3; i++) cout << *vec[i] << endl; 
    cout <<"size of vec " <<vec.size() << endl; 
    mem_manager.DumpMemoryInfo(); 

    return 0; 
} 

的LxUNIXsys是,我使用的一类内存转储,我从它调用的方法是:

void LxUNIXsys::DumpMemoryInfo() { 

    pid_t id = getpid(); 
    // cout << "id = " << id << endl; 
    stringstream ss(""); 
    ss << "pmap -d " << id << " | grep private "; 
    // cout << ss.str().c_str() << endl; 
    cout << "Memory dump: [pid = " << id << " ] " << flush; system(ss.str().c_str()); 
} 

我得到的输出是:

Memory dump: [pid = 17012 ] mapped: 51476K writeable/private: 7452K shared: 0K 

3 
3 
3 
Memory dump: [pid = 17012 ] mapped: 51480K writeable/private: 7456K shared: 0K 

3 
3 
3 
size of vec 0 
Memory dump: [pid = 17012 ] mapped: 51480K writeable/private: 7456K shared: 0K 

所以,巴我删除了指针,不仅信息仍然存在,但我可以在clear()后访问它。

我也尝试使用delete[]删除vec,但结果是一样的。 PS:我知道智能指针的存在,但我想知道为什么这段代码没有达到预期的效果。 PPS:我知道未定义的行为,在清除后忘记访问,我只是想要一种有效的方式来立即释放内存,就像我删除常规指针时一样。

+0

你知道你做错了事,你为什么对结果感到惊讶? – 2013-04-09 10:10:41

+0

删除不会清除其内部数据。 – phoeagon 2013-04-09 10:11:08

+0

你专注于错误的事情。请阅读我的其他评论。 – gonsuh 2013-04-09 10:24:42

回答

4

您有未定义的行为。这是由于您访问您的std::vector中不存在的元素造成的。未定义的行为意味着任何事情都可能发生。它甚至可能看起来应该被销毁的物体仍然存在。

C++标准没有提到操作系统应如何管理内存的分配和释放。它只是给你的程序可以依赖的规则。没有理由为这三个double s分配的内存实际上无法在操作系统中比您要求的时间晚回收。你再也不能依靠它了。你唯一可以依靠的是你不应该访问你的std::vector的界限之外。

这正是为什么这被标准规定为未定义的行为。它为操作系统或环境提供了执行其内存管理的余地,但它仍然为您的程序提供依赖于明确定义的行为的规则。

+0

那么,为什么不记得呢? – gonsuh 2013-04-09 10:11:28

+0

@贡萨洛见我的编辑。 – 2013-04-09 10:11:40

+0

但我有一个算法,需要有一个相似类型的矢量在一个for循环的迭代中立即释放。这种方法有没有办法做到这一点?当我删除一个不在矢量内的指针时,内存立即被释放...... – gonsuh 2013-04-09 10:14:52

0

我认为这个问题是您正在阅读的载体方式:

for(int i =0; i < 3; i++) 

这一行你正在阅读超越矢量结束。 即使它的内容被删除,它可能会停留在内存中一段时间​​。这意味着一旦它被删除,就不能再确定这些位置上保存的是删除之前存储的内容,但它可以是您存储的内容。

这就像从你的HD删除文件。这些位实际上在那里被重写,它们只是被设置为未被使用。

1

删除从免费商店分配的内存不保证将其返回到操作系统或使其无法访问。通常情况下,小分配由您的流程中的堆管理;它从系统中分配一大块,并分配小块;删除的内存返回到该堆。这比每次分配进入系统要高效得多。

这意味着删除的内存仍然可以访问,并且在重用之前可能仍然包含删除后的任何数据。因此访问它会导致未定义的行为,而不是任何明确定义的错误。