-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().

我也尝试过删除 vec usingdelete[]但结果是一样的。

PS:我知道智能指针的存在,但我想知道为什么这段代码没有达到预期的效果。

PPS:我知道未定义的行为,忘记清除后的访问,我只想要一种有效的方法来立即释放内存,比如删除常规指针时。

4

3 回答 3

4

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

C++ 标准没有说明操作系统应该如何管理内存的分配和释放。它只是给出了关于你的程序可以依赖什么的规则。没有理由说,分配给这三个doubles 的内存实际上不能在您要求的时间稍晚一点后被操作系统回收。你不能再依赖它了。您唯一可以依靠的是您不应该在std::vector.

这正是标准将其指定为未定义行为的原因。它为操作系统或环境提供了执行其内存管理的余地,无论它选择如何,同时仍然为您的程序提供了可以依赖的规则来实现明确定义的行为。

于 2013-04-09T10:08:46.607 回答
1

删除从空闲存储区分配的内存不能保证将其返回给操作系统,或使其不可访问。通常,小分配由进程中的堆管理;它从系统中分配一个大块,并分配较小的块;删除的内存返回到该堆。这比每次分配都进入系统要有效得多。

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

于 2013-04-09T10:14:02.373 回答
0

我认为问题在于您阅读矢量的方式:

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

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

这就像从 HD 中删除文件一样。在重写之前,这些位实际上是存在的,它们只是被设置为未使用。

于 2013-04-09T10:12:11.940 回答