📄 testmemleak.cpp
字号:
void ret5() { check("static char * f()\n" "{\n" " char *c = new char[50];\n" " return (c ? c : NULL);\n" "}\n"); ASSERT_EQUALS(std::string(""), errout.str()); } void ret6() { check("void foo()\n" "{\n" " char *c = new char[50];\n" " return strcpy(c, \"foo\");\n" "}\n"); ASSERT_EQUALS(std::string(""), errout.str()); } void ret7() { check("void foo()\n" "{\n" " char *c = new char[50];\n" " return memcpy(c, \"foo\",4);\n" "}\n"); ASSERT_EQUALS(std::string(""), errout.str()); } void mismatch1() { check("void f()\n" "{\n" " int *a = new int[10];\n" " free(a);\n" "}\n", true); ASSERT_EQUALS(std::string("[test.cpp:4]: (error) Mismatching allocation and deallocation: a\n"), errout.str()); } void mismatch2() { check("void f()\n" "{\n" " FILE *fp;\n" "\n" " fp = fopen();\n" " fclose(fp);\n" "\n" " fp = popen();\n" " pclose(fp);\n" "}\n", false); ASSERT_EQUALS(std::string(""), errout.str()); } void mismatch3() { check("void f()\n" "{\n" " FILE *fp;\n" "\n" " if (abc) fp = fopen();\n" " else fp = popen();\n" "\n" " if (abc) fclose(fp);\n" " else pclose(fp);\n" "}\n", false); ASSERT_EQUALS(std::string(""), errout.str()); } void mismatch4() { check("void f()\n" "{\n" " char *p = 0;\n" " for (i = 0; i < 10; ++i)\n" " {\n" " delete p;\n" " p = new char[100];\n" " }\n" " delete [] p;\n" "}\n", false); ASSERT_EQUALS(std::string("[test.cpp:7]: (error) Mismatching allocation and deallocation: p\n"), errout.str()); } //////////////////////////////////////////////// // function calls //////////////////////////////////////////////// void func1() { check("static void f()\n" "{\n" " char *p = new char[100];\n" " foo(p);\n" "}\n"); ASSERT_EQUALS(std::string(""), errout.str()); } void func2() { check("static void f()\n" "{\n" " char *p = new char[100];\n" " foo.add(p);\n" "}\n"); ASSERT_EQUALS(std::string(""), errout.str()); } void func3() { check("static void foo(const char *str)\n" "{ }\n" "\n" "static void f()\n" "{\n" " char *p = new char[100];\n" " foo(p);\n" "}\n"); ASSERT_EQUALS(std::string("[test.cpp:8]: (error) Memory leak: p\n"), errout.str()); } void func4() { check("static void foo(char *str)\n" "{\n" " delete [] str;\n" "}\n" "\n" "static void f()\n" "{\n" " char *p = new char[100];\n" " foo(p);\n" "}\n"); ASSERT_EQUALS(std::string(""), errout.str()); } void func5() { check("static void foo(char *str)\n" "{\n" " delete str;\n" "}\n" "\n" "static void f()\n" "{\n" " char *p = new char[100];\n" " foo(p);\n" "}\n", true); std::string err(errout.str()); ASSERT_EQUALS(std::string("[test.cpp:9] -> [test.cpp:3]: (error) Mismatching allocation and deallocation: str\n"), err); } void func6() { check("static void foo(char *str)\n" "{\n" " goto abc;\n" "}\n" "\n" "static void f()\n" "{\n" " char *p = new char[100];\n" " foo(p);\n" "}\n"); std::string err(errout.str()); ASSERT_EQUALS(std::string("[test.cpp:10]: (error) Memory leak: p\n"), err); } void func7() { check("static void foo(char *str)\n" "{\n" " if (abc)\n" " return;" " delete [] str;\n" "}\n" "\n" "static void f()\n" "{\n" " char *p = new char[100];\n" " foo(p);\n" "}\n"); std::string err(errout.str()); ASSERT_EQUALS(std::string("[test.cpp:11]: (error) Memory leak: p\n"), err); } void func8() { check("static void foo()\n" "{\n" " char *str = new char[100];" " (*release)(str);\n" "}\n"); ASSERT_EQUALS(std::string(""), errout.str()); } void func9() { check("int b()\n" "{\n" " return 0;\n" "}\n" "\n" "void a()\n" "{\n" " char *a = new char[10];\n" " if (b())\n" " return;\n" " delete [] a;\n" "}\n"); ASSERT_EQUALS(std::string(""), errout.str()); } void func10() { check("static void f(void (*fnc)(char*))\n" "{\n" " char *c = malloc(50);\n" " (fnc)(c);\n" "}\n"); ASSERT_EQUALS(std::string(""), errout.str()); } void func11() { check("static void f(struct1 *s1)\n" "{\n" " char *c = malloc(50);\n" " (s1->fnc)(c);\n" "}\n"); ASSERT_EQUALS(std::string(""), errout.str()); } void func12() { check("void add_list(struct mmtimer *n)\n" "{\n" " rb_link_node(&n->list, parent, link);\n" "}\n" "\n" "int foo()\n" "{\n" " struct mmtimer *base;\n" "\n" " base = kmalloc(sizeof(struct mmtimer), GFP_KERNEL);\n" " if (base == NULL)\n" " return -ENOMEM;\n" "\n" " add_list(base);\n" "}\n"); ASSERT_EQUALS(std::string(""), errout.str()); } void func13() { check("static void f()\n" "{\n" " char *p = malloc(100);\n" " foo(&p);\n" "}\n"); ASSERT_EQUALS(std::string(""), errout.str()); } /* void func3() { check( "static char *dmalloc()\n" "{\n" " char *p = new char[100];\n" " return p;\n" "}\n" "static void f()\n" "{\n" " char *p = dmalloc();\n" "}\n" ); ASSERT_EQUALS( std::string("[test.cpp:9]: Memory leak: p\n"), errout.str() ); } void func4() { check( "static char *dmalloc()\n" "{\n" " char *p = new char[100];\n" " return p;\n" "}\n" "static void f()\n" "{\n" " char *p = dmalloc();\n" " delete p;\n" "}\n" ); ASSERT_EQUALS( std::string("[test.cpp:9]: Mismatching allocation and deallocation: p\n"), errout.str() ); } */ void class1() { check("class Fred\n" "{\n" "private:\n" " char *str1;\n" " char *str2;\n" "public:\n" " Fred();\n" " ~Fred();\n" "};\n" "\n" "Fred::Fred()\n" "{\n" " str1 = new char[10];\n" " str2 = new char[10];\n" "}\n" "\n" "Fred::~Fred()\n" "{\n" " delete [] str2;\n" "}\n", true); ASSERT_EQUALS(std::string("[test.cpp:4]: (all) Memory leak: Fred::str1\n"), errout.str()); } void class2() { check("class Fred\n" "{\n" "private:\n" " char *str1;\n" "public:\n" " Fred();\n" " ~Fred();\n" "};\n" "\n" "Fred::Fred()\n" "{\n" " str1 = new char[10];\n" "}\n" "\n" "Fred::~Fred()\n" "{\n" " free(str1);\n" "}\n", true); ASSERT_EQUALS(std::string("[test.cpp:17]: (error) Mismatching allocation and deallocation: Fred::str1\n"), errout.str()); } void class3() { check("class Token;\n" "\n" "class Tokenizer\n" "{\n" "private:\n" " Token *_tokens;\n" "\n" "public:\n" " Tokenizer();\n" " ~Tokenizer();\n" " void deleteTokens(Token *tok);\n" "};\n" "\n" "Tokenizer::Tokenizer()\n" "{\n" " _tokens = new Token;\n" "}\n" "\n" "Tokenizer::~Tokenizer()\n" "{\n" " deleteTokens(_tokens);\n" "}\n" "\n" "void Tokenizer::deleteTokens(Token *tok)\n" "{\n" " while (tok)\n" " {\n" " Token *next = tok->next();\n" " delete tok;\n" " tok = next;\n" " }\n" "}\n", true); ASSERT_EQUALS(std::string(""), errout.str()); } void class4() { check("struct ABC;\n" "class Fred\n" "{\n" "private:\n" " void addAbc(ABC *abc);\n" "public:\n" " void click();\n" "};\n" "\n" "void Fred::addAbc(ABC* abc)\n" "{\n" " AbcPosts->Add(abc);\n" "}\n" "\n" "void Fred::click()\n" "{\n" " ABC *p = new ABC;\n" " addAbc( p );\n" "}\n"); ASSERT_EQUALS("", errout.str()); } void class5() { check("class Fred\n" "{\n" "public:\n" " void foo();\n" "};\n" "\n" "void Fred::foo()\n" "{\n" " char *str = new char[100];\n" "}\n"); ASSERT_EQUALS("[test.cpp:10]: (error) Memory leak: str\n", errout.str()); } void class6() { check("class Fred\n" "{\n" "public:\n" " void foo();\n" "};\n" "\n" "void Fred::foo()\n" "{\n" " char *str = new char[100];\n" " delete [] str;\n" " hello();\n" "}\n"); ASSERT_EQUALS("", errout.str()); } void class7() { check("class Fred\n" "{\n" "public:\n" " int *i;\n" " Fred();\n" " ~Fred();\n" "};\n" "\n" "Fred::Fred()\n" "{\n" " this->i = new int;\n" "}\n" "Fred::~Fred()\n" "{\n" " delete this->i;\n" "}\n", true); ASSERT_EQUALS("", errout.str()); } void class8() { check("class A\n" "{\n" "public:\n" " void a();\n" " void doNothing() { }\n" "};\n" "\n" "void A::a()\n" "{\n" " int* c = new int(1);\n" " delete c;\n" " doNothing(c);\n" "}\n"); ASSERT_EQUALS("", errout.str());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -