我的代码如下所示:
bool
amflinkd_apteryx_set_action (const char *address, char *action)
{
bool ret = false;
char *path = NULL;
if (asprintf (&path, "%s/%s", AMFLINKD_IP_ADDRESS_PATH, address) > 0)
{
ret = apteryx_set_string (path, "action", action);
}
free (path);
return ret;
}
然后我对它执行单元测试,在其上执行valgrind。我的输出是:
np: running: "amflinkd_apteryx_unit_tests.amflinkd_apteryx_set_action_true"
EVENT SLMATCH err: SET: Not initialised
at 0x805B512: np::spiegel::describe_stacktrace (np/spiegel/spiegel.cxx)
by 0x804BAD3: np::event_t::with_stack (np/event.cxx)
by 0x8067688: np::mock_syslog (isyslog.c)
by 0x8079EA8: np::spiegel::platform::intercept_tramp (np/spiegel/platform/linux_x86.cxx)
by 0x412BC71:
==4== 33 bytes in 1 blocks are definitely lost in loss record 323 of 525
==4== at 0x402B19B: malloc (vg_replace_malloc.c:299)
==4== by 0x47ECAA7: vasprintf (vasprintf.c:73)
==4== by 0x47CFEEA: asprintf (asprintf.c:35)
==4== by 0x804B392: amflinkd_apteryx_set_action (amflinkd_apteryx.c:33)
==4== by 0x804B28F: test_amflinkd_apteryx_set_action_true (amflinkd_apteryx_unit_tests.c:38)
==4== by 0x805B0F1: np::spiegel::function_t::invoke(std::vector<np::spiegel::value_t, std::allocator<np::spiegel::value_t> >) const (spiegel.cxx:606)
==4== by 0x804F68A: np::runner_t::run_function(np::functype_t, np::spiegel::function_t*) (runner.cxx:526)
==4== by 0x804FEF6: np::runner_t::run_test_code(np::job_t*) (runner.cxx:650)
==4== by 0x805019D: np::runner_t::begin_job(np::job_t*) (runner.cxx:710)
==4== by 0x804E694: np::runner_t::run_tests(np::plan_t*) (runner.cxx:147)
==4== by 0x8050374: np_run_tests (runner.cxx:822)
==4== by 0x804BA7D: main (main.c:108)
==4==
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:malloc
fun:vasprintf
fun:asprintf
fun:amflinkd_apteryx_set_action
fun:test_amflinkd_apteryx_set_action_true
fun:_ZNK2np7spiegel10function_t6invokeESt6vectorINS0_7value_tESaIS3_EE
fun:_ZN2np8runner_t12run_functionENS_10functype_tEPNS_7spiegel10function_tE
fun:_ZN2np8runner_t13run_test_codeEPNS_5job_tE
fun:_ZN2np8runner_t9begin_jobEPNS_5job_tE
fun:_ZN2np8runner_t9run_testsEPNS_6plan_tE
fun:np_run_tests
fun:main
}
==4== 40 bytes in 1 blocks are definitely lost in loss record 335 of 525
==4== at 0x402B19B: malloc (vg_replace_malloc.c:299)
==4== by 0x47ECAA7: vasprintf (vasprintf.c:73)
==4== by 0x47CFEEA: asprintf (asprintf.c:35)
==4== by 0x412D10B: apteryx_cas_string (apteryx.c:530)
==4== by 0x412D1BC: apteryx_set_string (apteryx.c:544)
==4== by 0x804B3B0: amflinkd_apteryx_set_action (amflinkd_apteryx.c:35)
==4== by 0x804B28F: test_amflinkd_apteryx_set_action_true (amflinkd_apteryx_unit_tests.c:38)
==4== by 0x805B0F1: np::spiegel::function_t::invoke(std::vector<np::spiegel::value_t, std::allocator<np::spiegel::value_t> >) const (spiegel.cxx:606)
==4== by 0x804F68A: np::runner_t::run_function(np::functype_t, np::spiegel::function_t*) (runner.cxx:526)
==4== by 0x804FEF6: np::runner_t::run_test_code(np::job_t*) (runner.cxx:650)
==4== by 0x805019D: np::runner_t::begin_job(np::job_t*) (runner.cxx:710)
==4== by 0x804E694: np::runner_t::run_tests(np::plan_t*) (runner.cxx:147)
==4==
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:malloc
fun:vasprintf
fun:asprintf
fun:apteryx_cas_string
fun:apteryx_set_string
fun:amflinkd_apteryx_set_action
fun:test_amflinkd_apteryx_set_action_true
fun:_ZNK2np7spiegel10function_t6invokeESt6vectorINS0_7value_tESaIS3_EE
fun:_ZN2np8runner_t12run_functionENS_10functype_tEPNS_7spiegel10function_tE
fun:_ZN2np8runner_t13run_test_codeEPNS_5job_tE
fun:_ZN2np8runner_t9begin_jobEPNS_5job_tE
fun:_ZN2np8runner_t9run_testsEPNS_6plan_tE
}
EVENT VALGRIND 73 bytes of memory leaked
EVENT VALGRIND 2 unsuppressed errors found by valgrind
FAIL amflinkd_apteryx_unit_tests.amflinkd_apteryx_set_action_true
第一次泄漏应该是&#34;路径&#34;指针,但我在返回之前释放它。 我不知道第二次泄漏是什么。
这是调用amflinkd_apteryx_set_action()函数的单元测试函数:
void
test_amflinkd_apteryx_set_action_true (void)
{
printf("Running test_amflinkd_apteryx_set_action_true test.");
const char *address = {"192.168.1.5"};
char *action = {"drop"};
bool res = amflinkd_apteryx_set_action (address, action);
NP_ASSERT_TRUE (res);
}
以下是apteryx_set_string()
的代码bool
apteryx_cas_string (const char *path, const char *key, const char *value, uint64_t ts)
{
char *full_path;
size_t len;
bool res = false;
/* Create full path */
if (key)
len = asprintf (&full_path, "%s/%s", path, key);
else
len = asprintf (&full_path, "%s", path);
if (len)
{
res = apteryx_cas (full_path, value, ts);
free (full_path);
}
return res;
}
bool
apteryx_set_string (const char *path, const char *key, const char *value)
{
return apteryx_cas_string (path, key, value, UINT64_MAX);
}
我重试了我的amflinkd_apteryx_set_action():
bool
amflinkd_apteryx_set_action (const char *address, char *action)
{
bool ret = false;
char *path = NULL;
if (asprintf (&path, "%s/%s", AMFLINKD_IP_ADDRESS_PATH, address) > 0)
{
ret = true; //apteryx_set_string (path, "action", action);
}
free (path);
return ret;
}
这没有内存泄漏。 然后我试了一下:
bool
amflinkd_apteryx_set_action (const char *address, char *action)
{
bool ret = false;
char *path = NULL;
if (asprintf (&path, "%s/%s", AMFLINKD_IP_ADDRESS_PATH, address) > 0)
{
ret = apteryx_test_string (path, "action", action);
}
free (path);
return ret;
}
与
bool
apteryx_test_string (const char *path, const char *key, const char *value)
{
char *full_path;
size_t len;
bool res = false;
/* Create full path */
if (key)
len = asprintf (&full_path, "%s/%s", path, key);
else
len = asprintf (&full_path, "%s", path);
if (len)
{
res = true;
free (full_path);
}
return res;
}
这也没有内存泄漏。它必须是apteryx_set_string()中的一个东西,它可以防止释放内存或丢失引用。
我明白了! 代码正在点击ASSERT
ASSERT ((ref_count > 0), return false, "SET: Not initialised\n");
apteryx_set_string()函数中有两个更深的调用。由于断言,free没有被调用,valgrind选择了内存泄漏。 谢谢你的帮助。
答案 0 :(得分:1)
我明白了! 代码正在点击ASSERT
ASSERT ((ref_count > 0), return false, "SET: Not initialised\n");
apteryx_set_string()函数中有两个更深的调用。由于断言,free没有被调用,valgrind选择了内存泄漏。 谢谢你的帮助。
答案 1 :(得分:-1)
这可能是一个范围问题。尝试在if块中释放。
在if语句中创建的变量,对于我的回忆,只存在于if块中。因此,你已经通过if块的右括号丢失了它。
当您在块之外声明变量时,在if语句期间调用asprintf()之前不会发生分配。
修改强> 为了提供更多信息,我的想法是asprintf是声明实际变量的那个,它给出的指针只是指向它。如果是这种情况,那么丢失的变量声明在if语句
中第二次修改 我测试了以下内容并且无法重现:
#include <stdlib.h>
#include <stdio.h>
void test() {
char *str = NULL;
if (asprintf(&str, "%s", "foo") > 0) {
printf("%s\n", str);
}
free(str);
}
int main() {
test();
return 0;
}
GCC命令行:
gcc -g -D_GNU_SOURCE -I/usr/include asprintf.c
输出:
valgrind ./a.out
==2461== Memcheck, a memory error detector
==2461== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==2461== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==2461== Command: ./a.out
==2461==
foo
==2461==
==2461== HEAP SUMMARY:
==2461== in use at exit: 0 bytes in 0 blocks
==2461== total heap usage: 3 allocs, 3 frees, 1,128 bytes allocated
==2461==
==2461== All heap blocks were freed -- no leaks are possible
==2461==
==2461== For counts of detected and suppressed errors, rerun with: -v
==2461== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)