首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++对象初始化与应用程序的堆使用分析

C++对象初始化与应用程序的堆使用分析
EN

Stack Overflow用户
提问于 2014-01-09 21:11:17
回答 1查看 171关注 0票数 1

请参阅下面的程序:

代码语言:javascript
复制
#include <cstdio>
#include <cstring>
#include <iostream>

class Chaine {
 private:
  char* _donnees;
  unsigned int _taille;

 public:
  Chaine();
  Chaine(const char*);
  ~Chaine();

  unsigned int taille() const;
};

Chaine::Chaine():_taille(0) {
  _donnees=new char[1];
  _donnees[0]='\0';
}

Chaine::Chaine(const char *s) { 
  _taille = std::strlen(s);

  _donnees = new char[_taille + 1];
  std::strcpy(_donnees, s);

  std::printf("%s(%d): %s\n", __FILE__, __LINE__, __func__);
}

Chaine::~Chaine() {
  if(*_donnees == 0){
      std::printf("_donnees points to freed block\n");
  }
  else{
      std::printf("_donnees points to freed block\n");
      delete[] _donnees;
      _donnees=NULL;
  }
  std::printf("%s(%d): %s\n", __FILE__, __LINE__, __func__);
}

unsigned int Chaine::taille() const{
    return _taille;
}

int main() {
    Chaine s1("une chaine"); 
    Chaine *s2 = new Chaine("s3");
    Chaine s3 = s1; 
    delete s2;
}

我使用g++ -Wall -o test test.cpp编译,然后运行valgrind --leak-check=full ./test并得到以下消息:

代码语言:javascript
复制
/test
==5638== Memcheck, a memory error detector
==5638== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==5638== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==5638== Command: ./test
==5638== 
test.cpp(29): Chaine
test.cpp(29): Chaine
_donnees points to freed block
test.cpp(41): ~Chaine
_donnees points to freed block
test.cpp(41): ~Chaine
==5638== Invalid read of size 1
==5638==    at 0x804886D: Chaine::~Chaine() (in /home/qliang/Documents/ENSEIRB/cpp/td2/chaine2/test)
==5638==    by 0x804895F: main (in /home/qliang/Documents/ENSEIRB/cpp/td2/chaine2/test)
==5638==  Address 0x4353028 is 0 bytes inside a block of size 11 free'd
==5638==    at 0x402B598: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==5638==    by 0x80488A3: Chaine::~Chaine() (in /home/qliang/Documents/ENSEIRB/cpp/td2/chaine2/test)
==5638==    by 0x8048953: main (in /home/qliang/Documents/ENSEIRB/cpp/td2/chaine2/test)
==5638== 
_donnees points to freed block
==5638== Invalid free() / delete / delete[] / realloc()
==5638==    at 0x402B598: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==5638==    by 0x80488A3: Chaine::~Chaine() (in /home/qliang/Documents/ENSEIRB/cpp/td2/chaine2/test)
==5638==    by 0x804895F: main (in /home/qliang/Documents/ENSEIRB/cpp/td2/chaine2/test)
==5638==  Address 0x4353028 is 0 bytes inside a block of size 11 free'd
==5638==    at 0x402B598: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==5638==    by 0x80488A3: Chaine::~Chaine() (in /home/qliang/Documents/ENSEIRB/cpp/td2/chaine2/test)
==5638==    by 0x8048953: main (in /home/qliang/Documents/ENSEIRB/cpp/td2/chaine2/test)
==5638== 
test.cpp(41): ~Chaine
==5638== 
==5638== HEAP SUMMARY:
==5638==     in use at exit: 0 bytes in 0 blocks
==5638==   total heap usage: 3 allocs, 4 frees, 22 bytes allocated
==5638== 
==5638== All heap blocks were freed -- no leaks are possible
==5638== 
==5638== For counts of detected and suppressed errors, rerun with: -v
==5638== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)

我是解构函数,我想检查内存_donnees指向的内存是否已被释放,以避免重新释放。一个解决方案(可能是不好的解决方案)是在解构函数中声明一个静态整数,如下

代码语言:javascript
复制
Chaine::~Chaine() {
  static int num_free = 0;
  if(num_free == 1){
      std::printf("_donnees points to freed block\n");
  }
  else{
      std::printf("_donnees points to freed block\n");
      delete[] _donnees;
      num_free = 1;
      _donnees=NULL;
  }
  std::printf("%s(%d): %s\n", __FILE__, __LINE__, __func__);
}

但是我想知道是否有像*_donnees == NULL这样的方式来检查内存块是否被释放。

还有,为什么val差尔会显示信息:

代码语言:javascript
复制
==5638== Invalid read of size 1
==5638== Invalid free() / delete / delete[] / realloc()

为什么每条信息都只显示一次?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-01-09 21:14:38

你违反了三条规则。您应该定义一个副本构造函数和一个副本赋值操作符。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21031220

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档