Векторы, указатели, кролики и исправление памяти вновь - PullRequest
0 голосов
/ 08 июля 2011

Краткое описание

В предыдущем посте я расспрашивал о проблеме с висящими указателями.Я понял, что мне рекомендуется использовать Boost , и я перепишу свою программу, как только я полностью получу основы классических указателей и управления памятью, поскольку, например, встроенные устройства содержат ограниченный набор библиотек lib и 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);
    }

}

Ответы [ 2 ]

1 голос
/ 08 июля 2011

Это поведение, связанное с системой, или я что-то забыл, чтобы фактически заставить переназначить память, назначенную процессу?

То, что вы сделали, правильно.То, что Вэлгринд сообщает, правильно.Операционная система должна решить, когда эта память может быть выделена другому процессу.Вы не всегда будете замечать уменьшение количества используемой памяти после удаления указателей на вашу собственную память.

1 голос
/ 08 июля 2011

ПОЭТОМУ, что отчет valgrind выглядит чистым (доступность часто происходит из стандартной библиотеки, например, std :: cout;

Вы, конечно, можете узнать (запустить с --leak-check=full -v), но будьте готовы пробираться по страницамложных срабатываний и / не-ваш-код / ​​ссылки

...