【问题标题】:memory leak in c++ and how to fix itC++中的内存泄漏以及如何修复它
【发布时间】:2022-01-01 17:12:54
【问题描述】:

我收到此错误与内存泄漏, 我知道我必须释放内存但是怎么做 我收到此错误与内存泄漏, 我知道我必须释放内存,但如何做请指导

SongCollection::SongCollection(char* filename) {
 try {
  std::ifstream file("songs.txt");
  if (file) {
   while (file) {
    std::string temp, t_artist, t_title, t_album, t_price, t_year, t_length;
    std::getline(file, temp, '\n'); 
    if (!(temp.length() < 25)) {
     t_title = temp.substr(0, 25); 
     t_artist = temp.substr(25, 25); 
     t_album = temp.substr(50, 25); 
     t_year = temp.substr(75, 5); 
     t_length = temp.substr(80, 5); 
     t_price = temp.substr(85, 5);
     auto strip = [&](std::string& str) { 
      str = str.substr(str.find_first_not_of(" "), str.find_last_not_of(" ") + 1); 
      str = str.substr(0, str.find_last_not_of(" ") + 1); 
     };
     strip(t_title); 
     strip(t_artist); 
     strip(t_album);
     m_storage = new Song;
     m_storage->m_title = t_title;
     m_storage->m_artist = t_artist;
     m_storage->m_album = t_album;
     try {
      m_storage->m_year = std::stoi(t_year);
     }
     catch (...) {
      m_storage->m_year = 0;
     }
     m_storage->m_length = std::stoi(t_length);
     m_storage->m_price = std::stod(t_price);
     collection.push_back(m_storage);
    }
   }
  }
  else {
   throw 1;
  }
 }
 catch (int& err) {
  std::cerr << "ERROR: Cannot open file [" << filename << "].\n";
  exit(err);
 }
}

SongCollection::~SongCollection() {
 if (m_storage) {
  delete m_storage;
  m_storage = nullptr;
 }
 collection.clear();
}

我收到了这个内存泄漏报告

==141379== 2,345 (2,128 direct, 217 indirect) bytes in 19 blocks are definitely lost in loss record 3 of 3 
==141379==    at 0x4C2A593: operator new(unsigned long) (vg_replace_malloc.c:344) 
==141379==    by 0x403991: sdds::SongCollection::SongCollection(char*) (SongCollection.cpp:34) 
==141379==    by 0x402856: main (w7_p2_prof.cpp:29)

【问题讨论】:

  • 处理 C++ 中所有内存泄漏的最佳方法是使用标头 &lt;memory&gt; 中的类,而不是手动管理它。 cplusplus.com/reference/memory
  • 首先m_storage不应该是成员变量。它应该是一个 local 变量。然后你有一个指针容器(collection),你永远不会删除这些对象。最后,这里根本不需要指针,而是使用 Song objects 的容器。
  • 在一些不相关的注释中,为什么你将filename 传递给SongCollection 构造函数,而不使用它?为什么字符串不是std::string?请在您的代码中添加一些空行以将其拆分为段落。这将使它更容易阅读。
  • 你能告诉我如何解决它
  • 您多次执行while (file),每次创建一首新歌曲 (m_storage = new Song;),但您只删除了析构函数中的一首歌曲。所有剩余的指针都将被覆盖并丢失,因为您将它们全部保存到同一个字段中。您可能想要一些指针列表。虽然,我对 Someprogrammerdude 有类似的怀疑。我不知道你为什么在这里甚至需要动态内存分配。

标签: c++ memory-leaks


【解决方案1】:

“最好的”™ 解决方案是根本不使用指针,因为这样就不会忘记删除动态分配。

对于您的情况,它包括一些相当小的更改以使其正常工作。

首先我建议您创建一个Song 构造函数,将所有需要的值作为参数,然后创建Song 对象变得更容易:

Song::Song(std::string const& title, std::string const& artist, std::string const& album, unsigned year)
    : m_title(title), m_artist(artist), m_album(album), m_year(year)
{
}

然后在 SongCollection 类中使用 Song 的向量 objects 而不是指针:

std::vector<Song> collection;

然后在创建对象的同时将歌曲添加到向量中:

 try {
  t_year = std::stoi(t_year);
 }
 catch (...) {
  t_year = 0;
 }

 collection.emplace_back(t_title, t_artist, t_album, t_year);

最后删除 SongCollection 析构函数。

没有指针,没有(显式)动态分配,没有内存泄漏。并且不会破坏the rules of three/five,遵循零规则。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-21
    • 1970-01-01
    • 2015-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-12
    相关资源
    最近更新 更多