向量、指针、兔子和内存回收
Vectors, Pointers, Rabbits and reclaiming memory revisited
简介
在之前的一篇文章中,我询问了关于悬空指针的问题。我明白我被建议使用Boost,一旦我完全掌握了经典指针和内存管理的基础知识,我就会重写我的程序,例如嵌入式设备携带一组有限的lib, Boost可能不可用,所以我希望能够做到这一点。
完整的解释到目前为止,我的程序创建了许多指向vector对象的指针。在函数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);
}
}
你所做的是对的。valgrind的报道是对的。由操作系统决定何时可以将内存分配给另一个进程。在删除指向内存的指针后,您并不总是会注意到内存使用计数的减少。这是系统相关的行为还是我忘记了一些东西来强制重新映射分配给进程的内存?
valgrind报告看起来很干净(可访问的通常来自标准库,例如std::cout;
您当然可以找到(运行--leak-check=full -v
),但要准备好涉水过假阳性和/not-your-code/引用的页面
相关文章:
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 如何理解将半精度指针转换为无符号长指针和相关的内存对齐
- CUDA:统一内存和指针地址的更改
- 在c++中为我自己的基于指针的数组分配内存的正确方法
- 为什么 vector 的随机访问迭代器给出与指针不同的内存地址?
- 当指向对象的指针作为参数传递给 std::thread 时,内存可见性
- 将统一的内存指针传递给内核会减慢程序的速度
- malloc - 运行时内存指针类型分配
- 共享内存指针分段错误
- 使用动态分配的内存(指针)
- 与对象一起返回时清除了内存指针
- 在UWP C++项目中,程序集分配的内存指针自动更改为0xffffffff
- 使用注入的 dll 使用内存指针编辑值
- 提升共享内存 - 指针的返回向量
- 监视从应用程序写入指定的内存指针从 DLL 接收
- 非分页内存指针
- Qt读取内存指针值
- 简单的程序帮助-发送动态内存指针到函数