📄 testmemleak.cpp
字号:
/* * Cppcheck - A tool for static C/C++ code analysis * Copyright (C) 2007-2009 Daniel Marjamäki, Reijo Tomperi, Nicolas Le Cam, * Leandro Penz, Kimmo Varis, Vesa Pikki * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/ */#include "../src/tokenize.h"#include "../src/checkmemoryleak.h"#include "testsuite.h"#include <iostream>#include <sstream>extern std::ostringstream errout;class TestMemleak : public TestFixture{public: TestMemleak() : TestFixture("TestMemleak") { }private: void check(const char code[], bool showAll = false) { // Tokenize.. Tokenizer tokenizer; std::istringstream istr(code); tokenizer.tokenize(istr, "test.cpp"); tokenizer.setVarId(); tokenizer.simplifyTokenList(); // Clear the error buffer.. errout.str(""); // Check for memory leaks.. Settings settings; settings._debug = true; settings._showAll = showAll; tokenizer.fillFunctionList(); CheckMemoryLeakClass checkMemoryLeak(&tokenizer, settings, this); checkMemoryLeak.CheckMemoryLeak(); } void run() { TEST_CASE(simple1); TEST_CASE(simple2); TEST_CASE(simple3); TEST_CASE(simple4); TEST_CASE(simple5); TEST_CASE(simple6); TEST_CASE(simple7); TEST_CASE(simple8); TEST_CASE(simple9); // Bug 2435468 - member function "free" TEST_CASE(simple10); // fclose in a if condition TEST_CASE(alloc_alloc_1); TEST_CASE(use1); TEST_CASE(use2); TEST_CASE(ifelse1); TEST_CASE(ifelse2); TEST_CASE(ifelse3); TEST_CASE(ifelse4); TEST_CASE(ifelse5); TEST_CASE(ifelse6); TEST_CASE(ifelse7); TEST_CASE(ifelse8); TEST_CASE(ifelse9); TEST_CASE(ifelse10); TEST_CASE(if1); TEST_CASE(if2); TEST_CASE(if3); TEST_CASE(if4); TEST_CASE(if5); TEST_CASE(if6); // Bug 2432631 TEST_CASE(if7); // Bug 2401436 TEST_CASE(if8); // Bug 2458532 // TODO TEST_CASE( if9 ); // if (realloc) TEST_CASE(if10); // else if (realloc) TEST_CASE(if11); TEST_CASE(forwhile1); TEST_CASE(forwhile2); TEST_CASE(forwhile3); TEST_CASE(forwhile4); TEST_CASE(forwhile5); TEST_CASE(forwhile6); TEST_CASE(forwhile7); TEST_CASE(forwhile8); // Bug 2429936 TEST_CASE(forwhile9); TEST_CASE(forwhile10); TEST_CASE(dowhile1); TEST_CASE(switch1); TEST_CASE(switch2); TEST_CASE(switch3); TEST_CASE(ret1); TEST_CASE(ret2); TEST_CASE(ret3); TEST_CASE(ret4); TEST_CASE(ret5); // Bug 2458436 - return use TEST_CASE(ret6); TEST_CASE(ret7); TEST_CASE(mismatch1); TEST_CASE(mismatch2); TEST_CASE(mismatch3); TEST_CASE(mismatch4); TEST_CASE(func1); TEST_CASE(func2); TEST_CASE(func3); TEST_CASE(func4); TEST_CASE(func5); TEST_CASE(func6); // TODO TEST_CASE( func7 ); TEST_CASE(func8); // Using callback TEST_CASE(func9); // Embedding the function call in a if-condition TEST_CASE(func10); // Bug 2458510 - Function pointer TEST_CASE(func11); // Bug 2458510 - Function pointer TEST_CASE(func12); TEST_CASE(func13); TEST_CASE(class1); TEST_CASE(class2); // TODO TEST_CASE( class3 ); TEST_CASE(class4); TEST_CASE(class5); TEST_CASE(class6); TEST_CASE(class7); TEST_CASE(class8); TEST_CASE(class9); TEST_CASE(throw1); TEST_CASE(throw2); TEST_CASE(linux_list_1); TEST_CASE(sizeof1); TEST_CASE(realloc1); TEST_CASE(realloc2); TEST_CASE(assign); // TODO TEST_CASE( varid ); TEST_CASE(cast1); TEST_CASE(cast2); TEST_CASE(cast3); // TODO TEST_CASE( structmember1 ); TEST_CASE(dealloc_use_1); // Deallocate and then use memory TEST_CASE(dealloc_use_2); // Deallocate and then use memory. No error if "use" is &var TEST_CASE(dealloc_use_3); // Deallocate and then use memory. No error TEST_CASE(dealloc_use_4); TEST_CASE(dealloc_use_5); TEST_CASE(dealloc_use_6); TEST_CASE(dealloc_use_7); // free a free'd pointer TEST_CASE(freefree1); TEST_CASE(freefree2); TEST_CASE(strcat_result_assignment); TEST_CASE(all1); // Extra checking when --all is given TEST_CASE(malloc_constant_1); // Check that the malloc constant matches the type // Calls to unknown functions.. they may throw exception, quit the program, etc TEST_CASE(unknownFunction1); TEST_CASE(unknownFunction2); TEST_CASE(unknownFunction3); // VCL.. TEST_CASE(vcl1); TEST_CASE(vcl2); } void simple1() { check("void f()\n" "{\n" " int *a = new int[10];\n" "}\n"); ASSERT_EQUALS(std::string("[test.cpp:4]: (error) Memory leak: a\n"), errout.str()); } void simple2() { check("Fred *NewFred()\n" "{\n" " Fred *f = new Fred;\n" " return f;\n" "}\n"); ASSERT_EQUALS(std::string(""), errout.str()); } void simple3() { check("static char *f()\n" "{\n" " char *s = new char[100];\n" " return (char *)s;\n" "}\n"); ASSERT_EQUALS(std::string(""), errout.str()); } void simple4() { check("static char *f()\n" "{\n" " char *s = new char[100];\n" " return 0;\n" "}\n"); ASSERT_EQUALS(std::string("[test.cpp:4]: (error) Memory leak: s\n"), errout.str()); } void simple5() { check("static char *f()\n" "{\n" " struct *str = new strlist;\n" " return &str->s;\n" "}\n"); ASSERT_EQUALS(std::string(""), errout.str()); } void simple6() { check("static void f()\n" "{\n" " char *str = strdup(\"hello\");\n" " char *str2 = (char *)str;\n" " free(str2);\n" "}\n"); ASSERT_EQUALS(std::string(""), errout.str()); } void simple7() { // A garbage collector may delete f automaticly check("class Fred;\n" "void foo()\n" "{\n" " Fred *f = new Fred;\n" "}\n"); ASSERT_EQUALS(std::string(""), errout.str()); } void simple8() { check("char * foo ()\n" "{\n" " char *str = strdup(\"abc\");\n" " if (somecondition)\n" " for (i = 0; i < 2; i++)\n" " { }\n" " return str;\n" "}\n"); ASSERT_EQUALS(std::string(""), errout.str()); } void simple9() { check("void foo()\n" "{\n" " MyClass *c = new MyClass();\n" " c->free(c);\n" " delete c;\n" "}\n"); ASSERT_EQUALS(std::string(""), errout.str()); } void simple10() { check("void foo()\n" "{\n" " FILE * f = fopen(fname, str);\n" " if ( fclose(f) != NULL );\n" "}\n"); ASSERT_EQUALS(std::string(""), errout.str()); } void alloc_alloc_1() { check("void foo()\n" "{\n" " char *str;\n" " str = new char[10];\n" " str = new char[20];\n" " delete [] str;\n" "}\n"); ASSERT_EQUALS(std::string("[test.cpp:5]: (error) Memory leak: str\n"), errout.str()); } void use1() { check("void foo()\n" "{\n" " char *str;\n" " if (somecondition)\n" " str = strdup(\"abc\");\n" " if (somecondition)\n" " DeleteString(str);\n" "}\n"); ASSERT_EQUALS(std::string(""), errout.str()); } void use2() { check("void foo()\n" "{\n" " char *str = strdup(\"abc\");\n" " if ( abc ) { memset(str, 0, 3); }\n" " *somestr = str;\n" "}\n"); ASSERT_EQUALS(std::string(""), errout.str()); } void ifelse1() { check("void f()\n" "{\n" " int *a = new int[10];\n" " if (a)\n" " {\n" " delete [] a;\n" " }\n" "}\n"); ASSERT_EQUALS(std::string(""), errout.str()); } void ifelse2() { check("void f()\n" "{\n" " char *str = strdup(\"hello\");\n" " if (somecondition)\n" " {\n" " return;\n" " }\n" " free(str);\n" "}\n"); ASSERT_EQUALS(std::string("[test.cpp:6]: (error) Memory leak: str\n"), errout.str()); } void ifelse3() { check("void f()\n" "{\n" " char *str = strdup(\"hello\");\n" " if (a==b)\n" " {\n" " free(str);\n" " return;\n" " }\n" "}\n"); ASSERT_EQUALS(std::string(""), errout.str()); check("void f()\n" "{\n" " char *str = strdup(\"hello\");\n" " if (a==b)\n" " {\n" " free(str);\n" " return;\n" " }\n" "}\n", true); ASSERT_EQUALS(std::string("[test.cpp:9]: (all) Memory leak: str\n"), errout.str()); } void ifelse4() { check("void f()\n" "{\n" " char *str = new char[10];\n" " if (a==b)\n" " {\n" " delete [] str;\n" " return;\n" " }\n" " delete [] str;\n" "}\n"); ASSERT_EQUALS(std::string(""), errout.str()); } void ifelse5() { check("void f()\n" "{\n" " char *str;\n" " if (somecondition)\n" " {\n" " str = new char[100];\n" " }\n" " else\n" " {\n" " return;\n" " }\n" " delete [] str;\n" "}\n"); ASSERT_EQUALS(std::string(""), errout.str()); } void ifelse6() { check("static char *f()\n" "{\n" " char *s = new char[100];\n" " if ( a == b )\n" " {\n" " return s;\n" " }\n" " return NULL;\n" "}\n"); ASSERT_EQUALS(std::string("[test.cpp:8]: (error) Memory leak: s\n"), errout.str()); } void ifelse7() { check("static char *f()\n" "{\n" " char *s;\n" " if ( abc )\n" " {\n" " s = new char[10];\n" " }\n" " return s;\n" "}\n"); ASSERT_EQUALS(std::string(""), errout.str()); } void ifelse8() { check("static char *f()\n" "{\n" " char *s = new char[10];\n" " if ( s )\n" " {\n" " return s;\n" " }\n" " return 0;\n" "}\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -