重新审视了载体,指针,兔子和回收记忆

时间:2011-07-08 10:09:55

标签: c++ pointers dynamic-memory-allocation delete-operator

简要说明

在上一篇文章中,我询问了悬挂指针的问题。 我知道我建议使用Boost并且我会在完全掌握有关经典指针和内存管理的基础知识之后重写我的程序,例如嵌入式设备带有一组有限的lib并且可能不会提升我希望能够以这种方式做到这一点。

完整解释

到现在为止,我的程序在向量中创建了许多指向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);
    }

}

2 个答案:

答案 0 :(得分:1)

FWIW,valgrind报告看起来很干净(可以经常从标准库中获取,例如std :: cout;

你当然可以找到(与--leak-check=full -v一起运行),但要准备好浏览误报和/或代码/参考的页面

答案 1 :(得分:1)

  

这个系统是否与行为有关,或者我是否忘记了实际强制重新映射分配给该过程的内存?

你所做的是对的。 valgrind报道的是正确的。由操作系统决定何时可以将该内存分配给另一个进程。在删除指向您拥有的内存的指针后,您并不总是会注意到内存使用量的减少。