简要说明
在上一篇文章中,我询问了一个关于悬空指针的问题。我知道有人建议我使用Boost,一旦我完全掌握了经典指针和内存管理的基础知识,我就会重写我的程序,因为例如嵌入式设备只能携带有限的库,而boost可能不可用,所以我希望能够以困难的方式做到这一点。
完整的解释
到目前为止,我的程序在一个向量中创建了很多指向Rabbit对象的指针。在函数pop_rabbits( Vector<Rabbit*>, int amount)中,我将尝试从内存中删除一些,并从向量中弹出指针,如下所示:
void pop_rabbits(vector<Rabbit*> & rabbits, int n){
vector<Rabbit*>::iterator rabbits_iterator ;
for(int r = 0 ; r < n ; r++ ){
Rabbit* dead_rabbit ;
dead_rabbit = rabbits.back() ;
delete dead_rabbit ;
rabbits.pop_back();
}
}但是当我查看进程的内存使用量时,它并没有减少。
Valgrind输出:
==26286==
==26286== HEAP SUMMARY:
==26286== in use at exit: 117,290 bytes in 6,471 blocks
==26286== total heap usage: 11,503 allocs, 5,032 frees, 222,872 bytes allocated
==26286==
==26286== LEAK SUMMARY:
==26286== definitely lost: 0 bytes in 0 blocks
==26286== indirectly lost: 0 bytes in 0 blocks
==26286== possibly lost: 0 bytes in 0 blocks
==26286== still reachable: 117,290 bytes in 6,471 blocks
==26286== suppressed: 0 bytes in 0 blocks
==26286== Rerun with --leak-check=full to see details of leaked memory
==26286==
==26286== For counts of detected and suppressed errors, rerun with: -v
==26286== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 18 from 7)这是与系统相关的行为,还是我忘记了什么,实际上强制重新映射分配给进程的内存?
源代码
/*
This will become an exercise on dynamic memory ;
Im going to create a lot of breeding rabbits :)
the application will wait for the user to give his fiat for mating, LOL
*/
using namespace std ;
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <iterator>
#include <sys/time.h>
#include <sys/resource.h>
class Rabbit {
public:
enum sexes { MALE = 0x1, FEMALE = 0x2 } ;
int sex ;
bool has_mated ;
Rabbit();
~Rabbit();
void setSexe(int sex);
void match( vector<Rabbit*> &rabbits ); //returns true if it found a female and makes the female breed.
void breed( Rabbit &partner, vector<Rabbit*> &rabbits ); //create ofspring from the female mixing in the genes from the male
};
Rabbit::Rabbit(){
this->sex = random() % 2 + 1 ; //random m/f
this->has_mated = false ;
}
Rabbit::~Rabbit(){
cout << "Aaaaahggg...beybeye cruel world !\n";
}
void Rabbit::setSexe( int sex ){
this->sex = sex ;
}
void Rabbit::match(vector<Rabbit*> &rabbits){
int s = rabbits.size() ;
int r = 0 ;
for(r ; r < s ; r++ ){
Rabbit* partner_ptr = rabbits.at(r) ;
if( partner_ptr->sex == Rabbit::MALE ){
this->breed(*partner_ptr, rabbits);
}
}
}
void Rabbit::breed( Rabbit &partner, vector<Rabbit*> &rabbits ){
int offspring, sex ;
offspring = random() % 4 + 3 ;
cout << "breeding " << offspring << " rabbits..." << endl ;
Rabbit* temp_rabbit ;
for(int i=0; i < offspring; i++){
int sex = random() % 2 + 1 ;
temp_rabbit = new Rabbit() ;
temp_rabbit->setSexe(sex);
rabbits.push_back(temp_rabbit);
cout << "one rabbit has been born." << endl ;
}
this->has_mated = true ;
}
//makes rabbits date each other
void match_rabbits(vector<Rabbit*> & rabbits){
cout << "matching rabbits..." << endl ;
for(int r = 0; r < rabbits.size() ; r++ ){
Rabbit* nth_rabbit_p = rabbits.at(r);
if( nth_rabbit_p->sex == Rabbit::FEMALE && nth_rabbit_p->has_mated == false){
cout << "found a female" << endl ;
nth_rabbit_p->match(rabbits) ;
break ;
}
}
}
void pop_rabbits(vector<Rabbit*> & rabbits, int n){
vector<Rabbit*>::iterator rabbits_iterator ;
for(int r = 0 ; r < n ; r++ ){
Rabbit* dead_rabbit ;
dead_rabbit = rabbits.back() ;
delete dead_rabbit ;
rabbits.pop_back();
}
}
int main( int argc , const char* argv[] ){
srand(time(NULL));
vector<Rabbit*> rabbits = vector<Rabbit*>(0) ;
Rabbit* adam ;
adam = new Rabbit();
adam->setSexe(Rabbit::MALE) ;
Rabbit* eve ;
eve = new Rabbit() ;
eve->setSexe(Rabbit::FEMALE) ;
char * input;
input = new char[2] ;
try{
//populate with 2 rabbits.
rabbits.push_back(adam);
rabbits.push_back(eve);
do {
//memory_usage = getrusage(RUSAGE_SELF, struct rusage *usage);
if(rabbits.size() < 2){
break ;
}
cout << rabbits.size() << " rabbits ( " << ( rabbits.size() * sizeof(Rabbit) )/1024 << "K )" << endl ;
cout << "Shoot some rabbits ? (Y/N) :" << endl ;
delete[] input ;
input = new char[2] ;
cin.getline(input,2);
if( strcmp(input,"Y") == 0 || strcmp(input,"y") == 0){
cout << "How many ? :" << endl ;
delete[] input ;
input = new char[16] ;
cin.getline(input,16);
pop_rabbits(rabbits, atoi(input));
continue ;
}
cout << "Continue ? (Y/Q) :" << endl ;
delete[] input ;
input = new char[2] ;
cin.getline(input,2);
if(strcmp(input,"Y") == 0 || strcmp(input,"y") == 0){
match_rabbits(rabbits);//let the rabbits date
}
if(strcmp(input,"Q") == 0 || strcmp(input,"q") == 0){
break ;
}
} while( true );
exit(0);
} catch ( exception& e ){
cout << e.what() << endl ; //print error
exit(1);
}
}发布于 2011-07-08 18:22:52
这是与系统相关的行为,还是我忘记了一些东西,实际上强制重新映射分配给进程的内存?
你所做的一切都是对的。valgrind所报道的是正确的。由操作系统决定何时可以将该内存分配给另一个进程。在删除指向您拥有的内存的指针后,您并不总是会注意到内存使用计数的减少。
发布于 2011-07-08 18:14:57
FWIW,valgrind报告看起来很干净(可访问的经常来自标准库,例如std::cout;
当然,您可以找到答案(使用--leak-check=full -v运行),但要准备好费力阅读大量的误报和/不是您的代码/引用
https://stackoverflow.com/questions/6622975
复制相似问题