堆腐败 - 矢量push_back

时间:2010-12-03 11:43:05

标签: c++ heap memory-corruption

我似乎有一个损坏的堆,我无法弄清楚为什么会发生这种情况....

以下是valgrind的追踪..

==12697== Use of uninitialised value of size 4
==12697==    at 0xDD0725: __gnu_cxx::__atomic_add(int volatile*, int) (in /usr/lib/libstdc++.so.6.0.7)
==12697==    by 0x1C3AD9BB: chargeRate::chargeRate(chargeRate const&) (in /root//app/libapp++.so)
==12697==    by 0x1C4C9C22: __gnu_cxx::__mt_alloc_base<chargeRate>::construct(chargeRate*, chargeRate const&) (mt_allocator.h:585)
==12697==    by 0x1C4CAC9F: std::vector<chargeRate, std::allocator<chargeRate> >::_M_insert_aux(__gnu_cxx::__normal_iterator<chargeRate*, std::vector<chargeRate, std::allocator<chargeRate> > >, chargeRate const&) (vector.tcc:284)
==12697==    by 0x1C4CAF9E: std::vector<chargeRate, std::allocator<chargeRate> >::push_back(chargeRate const&) (stl_vector.h:610)
==12697==    by 0x1C4C8A03: WebTranslations::getChargeDetails(std::vector<std::string, std::allocator<std::string> >&, std::vector<chargeRate, std::allocator<chargeRate> >&) (WebTranslations.cpp:427)
==12697==    by 0x1C4C8F83: WebTranslations::getChargeTranslations(std::vector<std::string, std::allocator<std::string> >&, std::vector<std::string, std::allocator<std::string> >&) (WebTranslations.cpp:1172)

==12697== 
==12697== Invalid read of size 4
==12697==    at 0xDB468B: std::string::string(std::string const&) (in /usr/lib/libstdc++.so.6.0.7)
==12697==    by 0x1C3AD9E0: chargeRate::chargeRate(chargeRate const&) (in /root//app/libapp++.so)
==12697==    by 0x1C4C9C22: __gnu_cxx::__mt_alloc_base<chargeRate>::construct(chargeRate*, chargeRate const&) (mt_allocator.h:585)
==12697==    by 0x1C4CAC9F: std::vector<chargeRate, std::allocator<chargeRate> >::_M_insert_aux(__gnu_cxx::__normal_iterator<chargeRate*, std::vector<chargeRate, std::allocator<chargeRate> > >, chargeRate const&) (vector.tcc:284)
==12697==    by 0x1C4CAF9E: std::vector<chargeRate, std::allocator<chargeRate> >::push_back(chargeRate const&) (stl_vector.h:610)
==12697==    by 0x1C4C8A03: WebTranslations::getChargeDetails(std::vector<std::string, std::allocator<std::string> >&, std::vector<chargeRate, std::allocator<chargeRate> >&) (WebTranslations.cpp:427)
==12697==    by 0x1C4C8F83: WebTranslations::getChargeTranslations(std::vector<std::string, std::allocator<std::string> >&, std::vector<std::string, std::allocator<std::string> >&) (WebTranslations.cpp:1172)
==12697==    by 0x1C299E48: zif__get_charge_translations (in /usr/lib/php4/.so)
==12697==    by 0x1BCE0916: zend_do_fcall_common_helper (in /usr/lib/httpd/modules/libphp5.so)
==12697==    by 0x1BCF1088: zend_do_fcall_handler (in /usr/lib/httpd/modules/libphp5.so)
==12697==    by 0x1BCDDD92: execute (in /usr/lib/httpd/modules/libphp5.so)
==12697==    by 0x1BCE02A9: zend_do_fcall_common_helper (in /usr/lib/httpd/modules/libphp5.so)
==12697==  Address 0xFFFFFFFC is not stack'd, malloc'd or (recently) free'd
==12697== 
==12697== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==12697==  GPF (Pointer out of bounds?)
==12697==    at 0xDB468B: std::string::string(std::string const&) (in /usr/lib/libstdc++.so.6.0.7)
==12697==    by 0x1C3AD9E0: chargeRate::chargeRate(chargeRate const&) (in /root//app/libapp++.so)
==12697==    by 0x1C4C9C22: __gnu_cxx::__mt_alloc_base<chargeRate>::construct(chargeRate*, chargeRate const&) (mt_allocator.h:585)
==12697==    by 0x1C4CAC9F: std::vector<chargeRate, std::allocator<chargeRate> >::_M_insert_aux(__gnu_cxx::__normal_iterator<chargeRate*, std::vector<chargeRate, std::allocator<chargeRate> > >, chargeRate const&) (vector.tcc:284)
==12697==    by 0x1C4CAF9E: std::vector<chargeRate, std::allocator<chargeRate> >::push_back(chargeRate const&) (stl_vector.h:610)
==12697==    by 0x1C4C8A03: WebTranslations::getChargeDetails(std::vector<std::string, std::allocator<std::string> >&, std::vector<chargeRate, std::allocator<chargeRate> >&) (WebTranslations.cpp:427)
==12697==    by 0x1C4C8F83: WebTranslations::getChargeTranslations(std::vector<std::string, std::allocator<std::string> >&, std::vector<std::string, std::allocator<std::string> >&) (WebTranslations.cpp:1172)

代码只是将结构推入向量。该结构中包含一些字符串变量。如果需要进一步调试,请告诉我。

有些消息来源:

typedef struct{
  string chargeType; // The name of the charge type, eg "Date Units"
  string unitSize;
  string rate;
  bool perConnection;
  string cap;
  bool useMaxDailyCharge;
  string maxDailyCharge;
  string identifier;
} chargeRate;

getChargeDetails:

vector<chargeRate> my_vector;
my_vector.push_back(this->getChargeRateDetails(chargeStructureNames[i]));

getChargeRateDetails:

where : vector<vector<string> > StringMatrix
StringMatrix *results; //used to retrive results from database.
chargeRate chargeInformation;
...
//populate results, check them
..
chargeInformation.chargeType = (*results)[FIRST_ROW][CHARGE_TYPE];
return chargeInformation;

编辑:我知道这是返回一个“副本”..这是完成测试一些事情,我将其插入到通过引用传递的向量副本中。

干杯!

3 个答案:

答案 0 :(得分:1)

看起来你的复制构造函数没有做正确的事情。为了将元素推送到矢量上,会创建chargeRate的副本。乍一看,

at 0xDD0725: __gnu_cxx::__atomic_add(int volatile*, int)
chargeRate::chargeRate(chargeRate const&)

告诉我,chargeRate复制构造函数尝试向未初始化的变量添加内容(由int volatile*的{​​{1}}参数指向。

你可能__atomic_add某个未初始化的成员变量。

__atomic_add

似乎是指StringMatrix *results; 的数组。有可能string未初始化良好。因此,第一行可能包含未初始化的StringMatrix - 类似内存,用于复制构造新对象的string成员。

chargeType类包含一个引用计数器,当新string指向同一数据时,需要增加该引用计数器,因此这可能有意义。

你可以通过(暂时)分配来验证这一点。一个空字符串而不是string

答案 1 :(得分:1)

如果getChargeRateDetails通过引用返回,则您尝试使用对已经超出范围的变量的引用。

答案 2 :(得分:0)

不确定您的应用程序中发生了什么,但可能与(不)使用back_inserter有关?

有一个很好的例子here