Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如果我为类型为“quot”的参数指定默认值;std::string&&引用;在C++;,这会导致内存泄漏吗?_C++_Memory Leaks_Valgrind_Stdstring - Fatal编程技术网

C++ 如果我为类型为“quot”的参数指定默认值;std::string&&引用;在C++;,这会导致内存泄漏吗?

C++ 如果我为类型为“quot”的参数指定默认值;std::string&&引用;在C++;,这会导致内存泄漏吗?,c++,memory-leaks,valgrind,stdstring,C++,Memory Leaks,Valgrind,Stdstring,我有一个这样声明的方法: /*! \brief Removes the leading and trailing white space from a string. \param s The string to remove the white space from. \param white_chars Characters to be considered as whitespace. */ std::string Trim(const std::string &s, const

我有一个这样声明的方法:

/*!
\brief Removes the leading and trailing white space from a string.
\param s The string to remove the white space from.
\param white_chars Characters to be considered as whitespace.
*/
std::string Trim(const std::string &s, const std::string &white_chars = " \t\n\r");
该方法的定义是无趣的,但无论如何,这里是:

std::string Trim(const std::string &s, const std::string &white_chars)
{
    size_t startidx = s.find_first_not_of(white_chars);
    if (startidx == std::string::npos) return "";
    size_t endidx = s.find_last_not_of(white_chars);
    return s.substr(startidx, endidx - startidx + 1);
}
现在在这个方法的大多数用法中,我只提供第一个参数。Valgrind给了我以下警告

==3338== 68 bytes in 2 blocks are possibly lost in loss record 4,639 of 7,212
==3338==    at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3338==    by 0x728CA88: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==3338==    by 0x728E2B4: char* std::string::_S_construct<char*>(char*, char*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==3338==    by 0x728E414: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&, unsigned long, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==3338==    by 0x728E441: std::string::substr(unsigned long, unsigned long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==3338==    by 0x6965F0A: str::Trim(std::string const&, std::string const&) (appbase.cpp:90)
==3338==    by 0x5F481D7: netopt::Element::set_ID(std::string const&) (netopt_elem.cpp:85)
==3338==7212的丢失记录4639中可能丢失了2个块中的68个字节
==3338==at 0x4C2B1C7:运算符新(无符号长)(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so中)
==3338==by 0x728CA88:std::string::_Rep::_S_create(无符号长、无符号长、std::分配器常量&)(in/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==3338==by 0x728E2B4:char*std::string::_S_构造(char*,char*,std::allocator const&,std::forward_iterator_标记)(in/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==3338==by 0x728E414:std::basic_string::basic_string(std::string const&,无符号长,无符号长)(in/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==3338==by 0x728E441:std::string::substr(无符号长,无符号长)const(in/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==3338==by 0x6965F0A:str::Trim(std::string const&,std::string const&)(appbase.cpp:90)
==3338==by 0x5F481D7:netopt::Element::set_ID(std::string const&)(netopt_elem.cpp:85)
注意“块可能丢失”?我见过Valgrind告诉我“块肯定丢失了”的内存泄漏,但这是一个不太确定的信息

那么问题就变成了,我给
std::string&
指定了一个默认值,是否导致了内存泄漏?如果是,我做错了什么?

没问题


在每次调用时构造临时字符串,并在语句末尾再次自动销毁。只要不保存对它的(悬空)引用,就没有问题。

通常,只有不带delete/free的new/malloc才会导致内存泄漏。在您的情况下,没有新的调用,因此应该没有内存泄漏。
“\t\n\r”
位于堆栈内存中,每次都会重复使用,以便为
std::string&white\u字符装入一个实例


在堆栈中创建并在函数返回后释放的临时实例。也没有内存泄漏。

没有技术问题,但从理论上讲,在每次调用时创建一个临时的
std::string
,并不太好。尤其是libstdc++(您似乎正在使用它),因为它每次都会导致内存分配(缺少短字符串优化)

由于
find\u first\u not\u有一个采用
char const*
的重载,因此最好提供两个重载:

// First, the one with the default argument, but without a temporary
std::string Trim(std::string const& s, char const* white_chars = " \t\n\r");

// Second, for convenience, one with a `std::string`
std::string Trim(std::string const& s, std::string const& white_chars);
这也意味着在调用
Trim(xx,“abc”)
时,将避免生成临时
std::string


当然,过度使用的解决方案是重用已经编写好的代码:有许多用于字符串操作的算法,包括。

那么您如何解释valgrind的内存泄漏报告呢?它表示字符串使用了
new
(虽然在'string::substr'中没有,但您的答案仍然不能解决任何问题。@Shahbaz:误诊?Valgrind以报告STL中的问题而闻名,我认为主要是因为STL分配器“缓存”了一些内存块以供以后重用。