本文介绍了字符串赋值中的内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我在C ++中运行单元测试时出现内存泄漏。

你可以看到函数的定义,以及这个函数使用的映射单元测试内存泄漏;



Hi,
I am getting a memory leak while running unit test in C++.
You can see definition of the function, and the map used by this function which casuses unit test memory leak;

const char* myMap [] =
{
     "INPUT1"        ,           "OUTPUT1",
     "INPUT2"        ,           "OUTPUT2",
     "INPUT3"        ,           "OUTPUT3",
     "INPUT4"        ,           "OUTPUT4",
     "INPUT5"        ,           "OUTPUT5",
     "INPUT6"        ,           "OUTPUT6",
     "INPUT7"        ,           "OUTPUT7",
     "INPUT8"        ,           "OUTPUT8",
     "INPUT9"        ,           "OUTPUT9",
     "INPUT10"       ,           "OUTPUT10",
     "THE_END"
};

const std::string Class::translateInput( const std::string& tag )
{
 static bool initialized = false;
 static map<std::string, std::string> m;
 if (!initialized)
 {
  initialized = true;
  unsigned long i = 0;
  static const std::string s = "THE_END";

  while( s != myMap[i])
  {
    std::string key = myMap[i];
    printf("\n 1. key is set to %s \n", myMap[i] );
    printf("\n m[ key ] is set to %s \n", myMap[i+1] );
    m[ key ] = myMap[i+1];
    i+=2;
   };
 }







这是valgrind的输出:



块大小:29,地址:0x5f40f44,返回跟踪:

2. /usr/lib/i386-linux-gnu/libstdc++.so.6(std: :string :: _ Rep :: _ S_create(unsigned int,unsigned int,std :: allocator< char> const&))[0x455f7d4]

3. / usr / lib / i386-linux-gnu / libstdc ++。so.6(std :: string :: _ M_mutate(unsigned int,unsigned int,unsigned int))[0x455fab4]

4. / usr / lib / i386-linux-gnu / libstdc ++。 so.6(std :: string :: _ M_replace_safe(unsigned int,unsigned int,char const *,unsigned int))[0x455fc42]

5. / usr / lib / i386-linux-gnu / libstdc ++。so.6(std :: string :: assign(char const *,unsigned int))[0x455fcf9]

6. /usr/lib/i386-linux-gnu/libstdc++.so。 6(std :: string :: operator =(char const *))[0x455ff06]

7. MyClass :: translateInput(std :: string const&))[0x43025c8]





它表示字符串分配的行如下所示;



m [key] = myMap [i + 1];



我之前放过痕迹,并在此之后。初始化后进行赋值时没有错误。在单元测试被拆除后,它给出了上面的输出。



我不知道内存泄漏的原因。您还可以看到,函数中没有指针或内存初始化。当我手动输入此函数的正确输出(translateInput)时(通过注释掉函数的调用),没有泄漏。每当我使用这个函数时,我都会得到上面提到的内存泄漏。



P.S:这个类的所有成员和函数MyClass都是静态的。



你能否帮助解决在这种状态下导致内存泄漏的可能原因?

在此先感谢,

Cranberries




Here is the output of valgrind :

Block size: 29, Address: 0x5f40f44, Back Trace:
2. /usr/lib/i386-linux-gnu/libstdc++.so.6(std::string::_Rep::_S_create(unsigned int, unsigned int, std::allocator<char> const&)) [0x455f7d4]
3. /usr/lib/i386-linux-gnu/libstdc++.so.6(std::string::_M_mutate(unsigned int, unsigned int, unsigned int)) [0x455fab4]
4. /usr/lib/i386-linux-gnu/libstdc++.so.6(std::string::_M_replace_safe(unsigned int, unsigned int, char const*, unsigned int)) [0x455fc42]
5. /usr/lib/i386-linux-gnu/libstdc++.so.6(std::string::assign(char const*, unsigned int)) [0x455fcf9]
6. /usr/lib/i386-linux-gnu/libstdc++.so.6(std::string::operator=(char const*)) [0x455ff06]
7. MyClass::translateInput(std::string const&)) [0x43025c8]


And it indicates the line where string assignment is made as the following ;

m[ key ] = myMap[i+1];

I've put traces before, and after this line. And there is no error while making assignment after initialization. After the unit test is teared down, it gives the above output.

I have no idea about the cause of memory leak. As you can also see, there is no pointer, or memory initialization in the function. And When I put the correct output of this function( translateInput ) manually ( by commenting out the call of function ), there is no leak. Whenever I use this function, I get the memory leak I mentioned above.

P.S: All members and functions of this class, MyClass, is static.

Could you please help about the possible reasons which cause memory leak in this state ?
Thanks in advance,
Cranberries

推荐答案


while( s != myMap[i])


#include <stdio.h>

static char *leaks;

int main(int argc, char *argv[])
{
    leaks = strdup("leaked data");
    puts(leaks);
    return 0;
}





如果它被分配一次 - 就像一个单身人士 - 并且在应用程序的生命周期中是需要的,那就没有真正需要回收它。操作系统将为您回收内存。



如果您担心堆报告工具中的混乱,您可以在程序退出时添加代码以释放它们:





If it is allocated once - like a singleton - and is needed for the life of the application, there's no real need to reclaim it. The OS will reclaim the memory for you.

If you are concerned by the clutter caused in your heap reporting tool, you can add code to free these at program exit:

#include <stdio.h>

static char *leaks;

int main(int argc, char *argv[])
{
    leaks = strdup("leaked data");
    puts(leaks);
    free(leaks);
    return 0;
}





作为旁注,请避免在不需要时使用哨兵值。 countof运算符将告诉您数组中有多少项。示例:





As a side note, avoid using sentinel values when they aren't necessary. The countof operator will tell you how many items are in an array. Example:

const char* myMap [] =
{
     "INPUT1"        ,           "OUTPUT1",
     "INPUT2"        ,           "OUTPUT2",
     "INPUT3"        ,           "OUTPUT3",
     "INPUT4"        ,           "OUTPUT4",
     "INPUT5"        ,           "OUTPUT5",
     "INPUT6"        ,           "OUTPUT6",
     "INPUT7"        ,           "OUTPUT7",
     "INPUT8"        ,           "OUTPUT8",
     "INPUT9"        ,           "OUTPUT9",
     "INPUT10"       ,           "OUTPUT10"
     // omit this: "THE_END"
};

for (size_t i = 0; i < countof(myMap); i++)
{
    const char *map = myMap[i];
    // ...
}





如果您的编译器没有countof(或)宏定义,使用:





If your compiler does not have a countof (or _countof) macro defined, use this:

#define countof(arg) ((sizeof arg) / (sizeof arg[0]))


这篇关于字符串赋值中的内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-14 16:16