泄漏在异常代码C ++ [英] Leak in Exception Code C++

查看:173
本文介绍了泄漏在异常代码C ++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在学校项目,其中一个任务是确保它不会泄漏。所以,我通过valgrind运行我的程序,并且因为我没有使用任何动态内存分配,我不认为我会找到任何东西。



。 Valgrind给了我这个:

  == 22107 == 1个块中的16个字节绝对会在丢失记录中丢失1个
== 22107 == at 0x100038915:malloc(vg_replace_malloc.c:236)
== 22107 == by 0x1000950CF:__cxa_get_globals(在/usr/lib/libstdc++.6.0.9.dylib)
== 22107 == by 0x100094DCD:__cxa_allocate_exception(在/usr/lib/libstdc++.6.0.9.dylib)
== 22107 == by 0x100051D42:std :: __ throw_out_of_range(char const *)(在/ usr / lib / libstdc ++。6.0.9.dylib)
== 22107 == by 0x100005463:std :: vector< std :: vector< int,std :: allocator< int> >,std :: allocator< std :: vector< int,std :: allocator< int> > > > :: _ M_range_check(unsigned long)const(in ./connect3)
== 22107 == by 0x100005482:std :: vector< std :: vector< int,std :: allocator< int> >,std :: allocator< std :: vector< int,std :: allocator< int> > > > :: at(unsigned long)(in ./connect3)
== 22107 == by 0x1000016E3:connect3 :: checkIfPositionIsBaseCase(Position)const(in ./connect3)
== 22107 == by 0x100007BD8:Game :: evaluate(Position)(in ./connect3)
== 22107 == by 0x100007D72:Game :: evaluate(Position)(in ./connect3)
== 22107 == by 0x1000043B4:main(in ./connect3)
== 22107 ==
== 22107 == LEAK摘要:
== 22107 ==明确丢失:1个块中有16个字节
== 22107 ==间接丢失:0字节在0块
== 22107 ==可能丢失:0字节在0块
== 22107 ==仍然可达:8,280字节3块
== 22107 == suppressed:0个块在0块
== 22107 ==可达块(未找到指针的块)不显示。
== 22107 ==查看它们,重新运行:--leak-check = full --show-reachable = yes

好吧,我看看它是从我的函数checkIfPositionIsBaseCase(Position)。看看这个方法(我的合作伙伴写的),我真的很惊讶看到可能导致泄漏的东西。



异常。这里是该函数的代码。

  //(这几乎是一样的,读取第一个try catch, / 
/// checkIfPositionIsBaseCase
///
bool connect3 :: checkIfPositionIsBaseCase(Position aPosition)const {

vector<载体, int> > thisP = aPosition.getBoard();

for(int w = 0; w for(int h = 0; h< thisP.at(w).size ); h ++){
int thisS = thisP.at(w).at(h);
if(thisS!= 0){
try {
if(thisP.at(w - 1).at(h - 1)== thisS){
if thisP.at(w - 2).at(h - 2)== thisS){
return true;
}
}
} catch(out_of_range&){}

try {
if(thisP.at(w).at(h - 1) )== thisS){
if(thisP.at(w).at(h - 2)== thisS){
return true;
}
}
} catch(out_of_range&){}

try {
if(thisP.at(w + 1).at - 1)== thisS){
if(thisP.at(w + 2).at(h - 2)== thisS){
return true;
}
}
} catch(out_of_range&){}

try {
if(thisP.at(w - 1).at )== thisS){
if(thisP.at(w - 2).at(h)== thisS){
return true;
}
}
} catch(out_of_range&){}

try {
if(thisP.at(w + 1).at )== thisS){
if(thisP.at(w + 2).at(h)== thisS){
return true;
}
}
} catch(out_of_range&){}

try {
if(thisP.at(w - 1).at + 1)== thisS){
if(thisP.at(w - 2).at(h + 2)== thisS){
return true;
}
}
} catch(out_of_range&){}

try {
if(thisP.at(w).at(h + 1 )== thisS){
if(thisP.at(w).at(h + 2)== thisS){
return true;
}
}
} catch(out_of_range&){}

try {
if(thisP.at(w + 1).at + 1)== thisS){
if(thisP.at(w + 2).at(h + 2)== thisS){
return true;
}
}
} catch(out_of_range&){}
}
}
}
///
/一种可能性
///
for(int i = 0; i for(int j = 0; j if(thisP.at(i).at(j)== 0){
return false;
}
}
}
return true;
}

我做了一些阅读,异常意味着我泄漏的记忆,但我不知道如何解决这个。如何重构代码,这样我不会泄漏内存?

解决方案

重要的是要了解泄漏内存之间的区别重复的基础(这可能导致耗尽),并且有一些底层支持代码或库有一个一次性的初始化步骤,它获得一些堆的内存,它将在程序运行时使用(在这种情况下,它不是真正有用或必要的免费/在程序终止时删除内存,这可能是一个麻烦,试图安排它。)



这里,__cxa_get_globals似乎是做一个一次性的malloc。 p>

简短的故事:只要确保你不会得到多个未发布的块(或更大的一个),当这些异常被重复调用....


I've been working with a school project, and one of the tasks is to make sure it doesn't leak at all. So, I ran my program through valgrind, and because I'm not using any dynamic memory allocation, I didn't think I would find anything.

Oops, I did. Valgrind gave me this:

==22107== 16 bytes in 1 blocks are definitely lost in loss record 1 of 4
==22107==    at 0x100038915: malloc (vg_replace_malloc.c:236)
==22107==    by 0x1000950CF: __cxa_get_globals (in /usr/lib/libstdc++.6.0.9.dylib)
==22107==    by 0x100094DCD: __cxa_allocate_exception (in /usr/lib/libstdc++.6.0.9.dylib)
==22107==    by 0x100051D42: std::__throw_out_of_range(char const*) (in /usr/lib/libstdc++.6.0.9.dylib)
==22107==    by 0x100005463: std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >::_M_range_check(unsigned long) const (in ./connect3)
==22107==    by 0x100005482: std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >::at(unsigned long) (in ./connect3)
==22107==    by 0x1000016E3: connect3::checkIfPositionIsBaseCase(Position) const (in ./connect3)
==22107==    by 0x100007BD8: Game::evaluate(Position) (in ./connect3)
==22107==    by 0x100007D72: Game::evaluate(Position) (in ./connect3)
==22107==    by 0x1000043B4: main (in ./connect3)
==22107== 
==22107== LEAK SUMMARY:
==22107==    definitely lost: 16 bytes in 1 blocks
==22107==    indirectly lost: 0 bytes in 0 blocks
==22107==      possibly lost: 0 bytes in 0 blocks
==22107==    still reachable: 8,280 bytes in 3 blocks
==22107==         suppressed: 0 bytes in 0 blocks
==22107== Reachable blocks (those to which a pointer was found) are not shown.
==22107== To see them, rerun with: --leak-check=full --show-reachable=yes

Well, I took a look at it is coming from my function "checkIfPositionIsBaseCase(Position)". Looking at this method (which my partner wrote), I was actually surprised to see something which may have caused the leak.

Exceptions. Here is the code for that function. (It's pretty much the same thing through out, read the first try catch and you've read them all).

///
/// checkIfPositionIsBaseCase
///
bool connect3::checkIfPositionIsBaseCase(Position aPosition) const {

    vector< vector< int > > thisP = aPosition.getBoard();

    for( int w = 0; w < thisP.size(); w++ ) {
        for( int h = 0; h < thisP.at(w).size(); h++ ){
            int thisS = thisP.at( w ).at( h );
            if( thisS != 0 ){
                try{
                    if( thisP.at( w - 1 ).at( h - 1 ) == thisS ){
                        if( thisP.at( w - 2 ).at( h - 2 ) == thisS ){
                            return true;
                        }
                    }
                }catch( out_of_range& ){}

                try{
                    if( thisP.at( w ).at( h - 1 ) == thisS ){
                        if( thisP.at( w ).at( h - 2 ) == thisS ){
                            return true;
                        }
                    }
                }catch( out_of_range& ){}

                try{
                    if( thisP.at( w + 1 ).at( h - 1 ) == thisS ){
                        if( thisP.at( w + 2 ).at( h - 2 ) == thisS ){
                            return true;
                        }
                    }
                }catch( out_of_range& ){}

                try{
                    if( thisP.at( w - 1 ).at( h ) == thisS ){
                        if( thisP.at( w - 2 ).at( h ) == thisS ){
                            return true;
                        }
                    }
                }catch( out_of_range& ){}

                try{
                    if( thisP.at( w + 1 ).at( h ) == thisS ){
                        if( thisP.at( w + 2 ).at( h ) == thisS ){
                            return true;
                        }
                    }
                }catch( out_of_range& ){}

                try{
                    if( thisP.at( w - 1 ).at( h + 1 ) == thisS ){
                        if( thisP.at( w - 2 ).at( h + 2 ) == thisS ){
                            return true;
                        }
                    }
                }catch( out_of_range& ){}

                try{
                    if( thisP.at( w ).at( h + 1 ) == thisS ){
                        if( thisP.at( w ).at( h + 2 ) == thisS ){
                            return true;
                        }
                    }
                }catch( out_of_range& ){}

                try{
                    if( thisP.at( w + 1 ).at( h + 1 ) == thisS ){
                        if( thisP.at( w + 2 ).at( h + 2 ) == thisS ){
                            return true;
                        }
                    }
                }catch( out_of_range& ){}
            }
        }
    }
    ///
    /// One possibility
    ///
    for (int i = 0; i < thisP.size(); i++) {
        for (int j = 0; j < thisP.at(i).size(); j++) {
            if (thisP.at(i).at(j) == 0) {
                return false;
            }
        }
    }
    return true;
}

I did a little reading, and it looks like the fact that I am catching exceptions means that I am leaking memory, but I don't know how to resolve this. How can I refactor the code so I don't leak memory?

解决方案

It's important to understand the difference between leaking memory on a repeated basis (which can lead to exhaustion), and having some underlying support code or library have a one-off intialisation step that gets some heap memory it will use while the program runs (in which case it's not really useful or necessary to free/delete the memory at program termination, and it may be quite a hassle trying to arrange it).

Here, __cxa_get_globals seems to be doing a one-off malloc.

Short story: just make sure you don't get multiple unreleased blocks (or a bigger one) when those exceptions are called repeatedly....

这篇关于泄漏在异常代码C ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆