تقارير Valgrind تسرب الذاكرة عند تعيين قيمة إلى سلسلة

StackOverflow https://stackoverflow.com/questions/1901322

سؤال

تبلغ Valgrind على تسرب الذاكرة عند تعيين قيمة إلى سلسلة.

لقد استخدمت التعليمات البرمجية البسيطة التالية لاختبار تسرب الذاكرة التي أبلغ عنها Valgrind.

/******************************************
* FILE: t3.c
* Compiled using : g++ -g t3.c -o t3
*
* $ g++ -v
* Reading specs from /usr/lib/gcc/i686-pc-linux-gnu/3.4.6/specs
* Configured with: ./configure --prefix=/usr --infodir=/share/info --mandir=/share/man
*      --enable-languages=c,c++ --with-system-zlib --program-suffix=-3.4 --enable-threads=posix
* Thread model: posix
* gcc version 3.4.6
 ******************************************/


#include <iostream>
#include <string>

using namespace std;

/**************************************************************
 **************************************************************/
int main(int argc, char *argv[])
{
   string test = "XXXXXXXXX";
   cout << "this is a test " << test << endl;
   exit(0);
}

أرخص باستخدام هذا الأمر:

$ g++ -g t3.c -o t3

وعندما أقوم بتشغيل Valgrind، قم بإبلاغ تسرب الذاكرة عند محاولة تعيين قيمة إلى سلسلة. أنا أستخدم هذا الاختبار البسيط للتحقيق في بعض تسرب الذاكرة في البرنامج الحقيقي، ويبدو أن استخدام السلسلة يمكن أن يسبب نوعا من المشكلة.

بواسطة 0x8048A6F: Main (T3.C: 23) هو الخط: اختبار السلسلة = "XXXXXXXXX"؛ هل يمكن لشخص ما أن يعطي بعض التلميح على هذا السلوك الغريب؟

[enzo@P0101222 C]$   valgrind --leak-check=full  ./t3
==3910== Memcheck, a memory error detector.
==3910== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==3910== Using LibVEX rev 1732, a library for dynamic binary translation.
==3910== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==3910== Using valgrind-3.2.3, a dynamic binary instrumentation framework.
==3910== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==3910== For more details, rerun with: -v
==3910==
this is a test XXXXXXXXX
==3910==
==3910== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 25 from 1)
==3910== malloc/free: in use at exit: 102 bytes in 3 blocks.
==3910== malloc/free: 4 allocs, 1 frees, 126 bytes allocated.
==3910== For counts of detected errors, rerun with: -v
==3910== searching for pointers to 3 not-freed blocks.
==3910== checked 194,136 bytes.
==3910==
==3910== 16 bytes in 1 blocks are definitely lost in loss record 1 of 3
==3910==    at 0x4017846: malloc (m_replacemalloc/vg_replace_malloc.c:149)
==3910==    by 0x4018E05: realloc (m_replacemalloc/vg_replace_malloc.c:306)
==3910==    by 0x41B441A: argz_append (in /lib/libc-2.2.5.so)
==3910==    by 0x41593B9: __newlocale (in /lib/libc-2.2.5.so)
==3910==    by 0x40E010B: std::locale::facet::_S_create_c_locale(__locale_struct*&, char const*, __locale_struct*) (c++locale.cc:99)
==3910==    by 0x407EF6F: std::locale::facet::_S_initialize_once() (../../.././libstdc++-v3/src/locale.cc:172)
==3910==    by 0x407EFB4: std::locale::facet::_S_get_c_locale() (../../.././libstdc++-v3/src/locale.cc:185)
==3910==    by 0x407A422: std::ctype<char>::ctype(unsigned short const*, bool, unsigned) (/usr3/BUILD/gcc/gcc-3.4.6/i686-pc-linux-gnu/libstdc++-v3/include/i686-pc-linux-gnu/bits/ctype_noninline.h:104)
==3910==    by 0x40801D5: std::locale::_Impl::_Impl(unsigned) (/usr3/BUILD/gcc/gcc-3.4.6/libstdc++-v3/libsupc++/new:92)
==3910==    by 0x4080EED: std::locale::_S_initialize_once() (/usr3/BUILD/gcc/gcc-3.4.6/libstdc++-v3/libsupc++/new:92)
==3910==    by 0x4080F84: std::locale::_S_initialize() (../../.././libstdc++-v3/src/locale_init.cc:155)
==3910==    by 0x4080FE7: std::locale::locale() (../../.././libstdc++-v3/src/locale_init.cc:102)
==3910==
==3910==
==3910== 22 bytes in 1 blocks are possibly lost in loss record 2 of 3
==3910==    at 0x4017C38: operator new(unsigned) (m_replacemalloc/vg_replace_malloc.c:163)
==3910==    by 0x40BF2C4: std::string::_Rep::_S_create(unsigned, unsigned, std::allocator<char> const&) (/usr3/BUILD/gcc/gcc-3.4.6/i686-pc-linux-gnu/libstdc++-v3/include/ext/new_allocator.h:81)
==3910==    by 0x40C1CE4: char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (/usr3/BUILD/gcc/gcc-3.4.6/i686-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.tcc:150)
==3910==    by 0x40C1E15: std::string::string(char const*, std::allocator<char> const&) (/usr3/BUILD/gcc/gcc-3.4.6/i686-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:1386)
==3910==    **by 0x8048A6F: main (t3.c:23)**
==3910==
==3910== LEAK SUMMARY:
==3910==    definitely lost: 16 bytes in 1 blocks.
==3910==      **possibly lost: 22 bytes in 1 blocks.**
==3910==    still reachable: 64 bytes in 1 blocks.
==3910==         suppressed: 0 bytes in 0 blocks.
==3910== Reachable blocks (those to which a pointer was found) are not shown.
==3910== To see them, rerun with: --leak-check=full --show-reachable=yes
[enzo@P0101222 C]$
هل كانت مفيدة؟

المحلول

لأنك تدعو exit(0), ، لذلك لا يتم الاحتجاج بالمدمر السلسلة. مجرد استخدام return 0.

لتوضيح، منشئ std::string يخصص الذاكرة الكهية لتخزين السلسلة، والاعتماد على المدمرات لإلغاء تخصيص هذه الذاكرة. إذا قمت بإعلان كائن سلسلة على المكدس، فسيتم استدعاء المدمرة تلقائيا عند الخروج من كائن السلسلة من النطاق، وبالتالي تحرير الذاكرة. ولكن exit هي حقا آلية ج؛ إنه يخرج على الفور البرنامج دون أداء تكدس يعني أن Dustructors C ++ لن يتم استدعاء كائنات المكدس المحلية.

نصائح أخرى

إذا قمت بتخصيص خمس سلاسل، فهل تحصل على تسرب الذاكرة خمس مرات، أم أنها لا تزال نفس الكمية؟ إذا كان نفس الكمية، فمن المحتمل أن يكون لديك تسرب على الإطلاق. بعض المكتبات تخصيص الذاكرة الخاصة بمسك الدفاتر / الكفاءة الداخلية / ET Cetera التي لا يتم إصدارها حتى بعد توقف Valgrind النظر. يتم التقاط هذه كتسربات للذاكرة لأن برنامجك تسبب في التخصيص ولكن لم تسبب أبدا في تخصيص. إذا كان ذلك خمس مرات المبلغ، فقد يكون تنفيذ السلسلة الخاص بك في خطأ. وأنا أتفق مع تشارلز سالفيا رغم ... حاول مرة أخرى مع return 0; بدلا من exit(0); ومعرفة ما إذا كان هذا يغير أي شيء.

في أحد فصول علوم الكمبيوتر الخاصة بي، قيل لنا أن Valgrind مخرجات معلومات حول السلاسل التي يجب ألا تقلق بشأنها. إليك ملف قمع أننا أعطانا سلاسل:https:/site.google.com/site/complingfiles/files/string.supp.

على الرغم من عدم وجود exit(0) في نهاية البرنامج كان لدي مشكلة مماثلة مع إيجابيات كاذبة مع std::string وبعد كنت مرتبطا قانونيا libstdc++. وبعد تبديل خيار ربط المشترك وتجميعها GLIBCXX_FORCE_NEW قمع التحذيرات.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top