【发布时间】:2021-10-18 14:59:44
【问题描述】:
所以我有以下代码:
int main(int, char **) {
auto wptr = new Fl_Double_Window{640,480};
wptr->show();
Fl::run();
return 0;
}
> valgrind --leak-check=full -s ./run
==13685== Memcheck, a memory error detector
==13685== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==13685== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
==13685== Command: ./run
==13685==
==13685==
==13685== HEAP SUMMARY:
==13685== in use at exit: 741,252 bytes in 1,107 blocks
==13685== total heap usage: 14,853 allocs, 13,746 frees, 2,829,612 bytes allocated
==13685==
==13685== LEAK SUMMARY:
==13685== definitely lost: 0 bytes in 0 blocks
==13685== indirectly lost: 0 bytes in 0 blocks
==13685== possibly lost: 0 bytes in 0 blocks
==13685== still reachable: 741,252 bytes in 1,107 blocks
==13685== suppressed: 0 bytes in 0 blocks
==13685== Reachable blocks (those to which a pointer was found) are not shown.
==13685== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==13685==
==13685== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 1 from 1)
--13685--
--13685-- used_suppression: 1 X on SUSE11 writev uninit padding /usr/lib/valgrind/default.supp:377
==13685==
==13685== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 1 from 1)
请注意,我没有删除指向窗口的指针,并且 valgrind 没有检测到任何泄漏。
我搜索了文档(https://www.fltk.org/doc-1.3/basics.html)以及常见问题解答页面(https://www.fltk.org/doc-1.3/FAQ.html、https://www.fltk.org/articles.php),我发现最新的分组小部件会自动附加新创建的小部件,但我什么也没找到关于 fltk 如何管理内存,例如,是否有一些“垃圾收集器”,或者我是否必须手动删除指针。
通常,此输出意味着存在一些负责释放内存的隐藏机制因为我没有手动释放分配给窗口的内存,而且似乎没有泄漏,但是看看对前面代码的以下修改:
int main(int, char **) {
auto wptr = new Fl_Double_Window{640,480};
auto box = new Fl_Box{0,0,100,100,"Hello!"}; // Adding widget
wptr->show();
Fl::run();
return 0;
}
valgrind --leak-check=full -s ./run
==14005== Memcheck, a memory error detector
==14005== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==14005== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
==14005== Command: ./run
==14005==
==14005==
==14005== HEAP SUMMARY:
==14005== in use at exit: 1,101,954 bytes in 11,185 blocks
==14005== total heap usage: 31,631 allocs, 20,446 frees, 7,013,742 bytes allocated
==14005==
==14005== 384 (256 direct, 128 indirect) bytes in 1 blocks are definitely lost in loss record 368 of 540
==14005== at 0x483E7C5: malloc (vg_replace_malloc.c:380)
==14005== by 0x4EC8255: ??? (in /usr/lib/libfontconfig.so.1.12.0)
==14005== by 0x4ECC200: ??? (in /usr/lib/libfontconfig.so.1.12.0)
==14005== by 0x4D433BF: ??? (in /usr/lib/libXft.so.2.3.4)
==14005== by 0x4D438F5: ??? (in /usr/lib/libXft.so.2.3.4)
==14005== by 0x4D43C96: ??? (in /usr/lib/libXft.so.2.3.4)
==14005== by 0x4D44080: XftDefaultHasRender (in /usr/lib/libXft.so.2.3.4)
==14005== by 0x4D44558: XftDefaultSubstitute (in /usr/lib/libXft.so.2.3.4)
==14005== by 0x4D46FD3: XftFontMatch (in /usr/lib/libXft.so.2.3.4)
==14005== by 0x4B30739: Fl_Font_Descriptor::Fl_Font_Descriptor(char const*, int, int) (in /usr/lib/libfltk.so.1.3.7)
==14005== by 0x4B309F2: ??? (in /usr/lib/libfltk.so.1.3.7)
==14005== by 0x4B337BB: fl_normal_label(Fl_Label const*, int, int, int, int, unsigned int) (in /usr/lib/libfltk.so.1.3.7)
==14005==
==14005== 2,565 (768 direct, 1,797 indirect) bytes in 1 blocks are definitely lost in loss record 482 of 540
==14005== at 0x484383F: realloc (vg_replace_malloc.c:1192)
==14005== by 0x4EC830E: ??? (in /usr/lib/libfontconfig.so.1.12.0)
==14005== by 0x4ED94DA: ??? (in /usr/lib/libfontconfig.so.1.12.0)
==14005== by 0x4ED156C: FcFontRenderPrepare (in /usr/lib/libfontconfig.so.1.12.0)
==14005== by 0x4ED1B9D: FcFontMatch (in /usr/lib/libfontconfig.so.1.12.0)
==14005== by 0x4D46FEF: XftFontMatch (in /usr/lib/libXft.so.2.3.4)
==14005== by 0x4B30739: Fl_Font_Descriptor::Fl_Font_Descriptor(char const*, int, int) (in /usr/lib/libfltk.so.1.3.7)
==14005== by 0x4B309F2: ??? (in /usr/lib/libfltk.so.1.3.7)
==14005== by 0x4B337BB: fl_normal_label(Fl_Label const*, int, int, int, int, unsigned int) (in /usr/lib/libfltk.so.1.3.7)
==14005== by 0x4B3390A: Fl_Widget::draw_label(int, int, int, int, unsigned int) const (in /usr/lib/libfltk.so.1.3.7)
==14005== by 0x4AD8D70: Fl_Group::draw_child(Fl_Widget&) const (in /usr/lib/libfltk.so.1.3.7)
==14005== by 0x4AD8F92: Fl_Group::draw_children() (in /usr/lib/libfltk.so.1.3.7)
==14005==
==14005== LEAK SUMMARY:
==14005== definitely lost: 1,024 bytes in 2 blocks
==14005== indirectly lost: 1,925 bytes in 69 blocks
==14005== possibly lost: 0 bytes in 0 blocks
==14005== still reachable: 1,099,005 bytes in 11,114 blocks
==14005== suppressed: 0 bytes in 0 blocks
==14005== Reachable blocks (those to which a pointer was found) are not shown.
==14005== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==14005==
==14005== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 1 from 1)
--14005--
--14005-- used_suppression: 1 X on SUSE11 writev uninit padding /usr/lib/valgrind/default.supp:377
==14005==
==14005== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 1 from 1)
现在似乎存在内存泄漏。似乎是字体库导致了这种情况。
我将再次修改代码以删除指向小部件的指针:
int main(int, char **) {
auto wptr = new Fl_Double_Window{640,480};
auto box = new Fl_Box{0,0,100,100,"Hello!"};
wptr->show();
Fl::run();
delete wptr;
delete box;
return 0;
}
> valgrind --leak-check=full ./run
==14238== Memcheck, a memory error detector
==14238== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==14238== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
==14238== Command: ./run
==14238==
==14238== Invalid read of size 8
==14238== at 0x1091CA: main (main.cpp:64)
==14238== Address 0x58a8730 is 0 bytes inside a block of size 120 free'd
==14238== at 0x48419AB: operator delete(void*, unsigned long) (vg_replace_malloc.c:814)
==14238== by 0x4AD862D: Fl_Group::clear() (in /usr/lib/libfltk.so.1.3.7)
==14238== by 0x4AD86E7: Fl_Group::~Fl_Group() (in /usr/lib/libfltk.so.1.3.7)
==14238== by 0x4AD1889: Fl_Double_Window::~Fl_Double_Window() (in /usr/lib/libfltk.so.1.3.7)
==14238== by 0x1091C0: main (main.cpp:63)
==14238== Block was alloc'd at
==14238== at 0x483EF3F: operator new(unsigned long) (vg_replace_malloc.c:417)
==14238== by 0x10915F: main (main.cpp:60)
==14238==
==14238== Jump to the invalid address stated on the next line
==14238== at 0x0: ???
==14238== by 0x51D4B24: (below main) (in /usr/lib/libc-2.33.so)
==14238== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==14238==
==14238==
==14238== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==14238== Bad permissions for mapped region at address 0x0
==14238== at 0x0: ???
==14238== by 0x51D4B24: (below main) (in /usr/lib/libc-2.33.so)
==14238==
==14238== HEAP SUMMARY:
==14238== in use at exit: 1,156,045 bytes in 11,490 blocks
==14238== total heap usage: 31,586 allocs, 20,096 frees, 7,058,062 bytes allocated
==14238==
==14238== 80 bytes in 1 blocks are possibly lost in loss record 277 of 558
==14238== at 0x483E7C5: malloc (vg_replace_malloc.c:380)
==14238== by 0x53E6D37: ??? (in /usr/lib/libGLdispatch.so.0.0.0)
==14238== by 0x53E73EE: __glDispatchInit (in /usr/lib/libGLdispatch.so.0.0.0)
==14238== by 0x54600AA: ??? (in /usr/lib/libGLX.so.0.0.0)
==14238== by 0x400FE2D: call_init (in /usr/lib/ld-2.33.so)
==14238== by 0x400FF1B: _dl_init (in /usr/lib/ld-2.33.so)
==14238== by 0x40010C9: ??? (in /usr/lib/ld-2.33.so)
==14238==
==14238== 80 bytes in 1 blocks are possibly lost in loss record 278 of 558
==14238== at 0x483E7C5: malloc (vg_replace_malloc.c:380)
==14238== by 0x53E6D37: ??? (in /usr/lib/libGLdispatch.so.0.0.0)
==14238== by 0x53E75D3: __glDispatchRegisterStubCallbacks (in /usr/lib/libGLdispatch.so.0.0.0)
==14238== by 0x538E076: ??? (in /usr/lib/libOpenGL.so.0.0.0)
==14238== by 0x400FE2D: call_init (in /usr/lib/ld-2.33.so)
==14238== by 0x400FF1B: _dl_init (in /usr/lib/ld-2.33.so)
==14238== by 0x40010C9: ??? (in /usr/lib/ld-2.33.so)
==14238==
==14238== 80 bytes in 1 blocks are possibly lost in loss record 279 of 558
==14238== at 0x483E7C5: malloc (vg_replace_malloc.c:380)
==14238== by 0x53E6D37: ??? (in /usr/lib/libGLdispatch.so.0.0.0)
==14238== by 0x53E75D3: __glDispatchRegisterStubCallbacks (in /usr/lib/libGLdispatch.so.0.0.0)
==14238== by 0x4A22076: ??? (in /usr/lib/libGL.so.1.7.0)
==14238== by 0x400FE2D: call_init (in /usr/lib/ld-2.33.so)
==14238== by 0x400FF1B: _dl_init (in /usr/lib/ld-2.33.so)
==14238== by 0x40010C9: ??? (in /usr/lib/ld-2.33.so)
==14238==
==14238== 384 (256 direct, 128 indirect) bytes in 1 blocks are definitely lost in loss record 380 of 558
==14238== at 0x483E7C5: malloc (vg_replace_malloc.c:380)
==14238== by 0x4EC8255: ??? (in /usr/lib/libfontconfig.so.1.12.0)
==14238== by 0x4ECC200: ??? (in /usr/lib/libfontconfig.so.1.12.0)
==14238== by 0x4D433BF: ??? (in /usr/lib/libXft.so.2.3.4)
==14238== by 0x4D438F5: ??? (in /usr/lib/libXft.so.2.3.4)
==14238== by 0x4D43C96: ??? (in /usr/lib/libXft.so.2.3.4)
==14238== by 0x4D44080: XftDefaultHasRender (in /usr/lib/libXft.so.2.3.4)
==14238== by 0x4D44558: XftDefaultSubstitute (in /usr/lib/libXft.so.2.3.4)
==14238== by 0x4D46FD3: XftFontMatch (in /usr/lib/libXft.so.2.3.4)
==14238== by 0x4B30739: Fl_Font_Descriptor::Fl_Font_Descriptor(char const*, int, int) (in /usr/lib/libfltk.so.1.3.7)
==14238== by 0x4B309F2: ??? (in /usr/lib/libfltk.so.1.3.7)
==14238== by 0x4B337BB: fl_normal_label(Fl_Label const*, int, int, int, int, unsigned int) (in /usr/lib/libfltk.so.1.3.7)
==14238==
==14238== 2,565 (768 direct, 1,797 indirect) bytes in 1 blocks are definitely lost in loss record 498 of 558
==14238== at 0x484383F: realloc (vg_replace_malloc.c:1192)
==14238== by 0x4EC830E: ??? (in /usr/lib/libfontconfig.so.1.12.0)
==14238== by 0x4ED94DA: ??? (in /usr/lib/libfontconfig.so.1.12.0)
==14238== by 0x4ED156C: FcFontRenderPrepare (in /usr/lib/libfontconfig.so.1.12.0)
==14238== by 0x4ED1B9D: FcFontMatch (in /usr/lib/libfontconfig.so.1.12.0)
==14238== by 0x4D46FEF: XftFontMatch (in /usr/lib/libXft.so.2.3.4)
==14238== by 0x4B30739: Fl_Font_Descriptor::Fl_Font_Descriptor(char const*, int, int) (in /usr/lib/libfltk.so.1.3.7)
==14238== by 0x4B309F2: ??? (in /usr/lib/libfltk.so.1.3.7)
==14238== by 0x4B337BB: fl_normal_label(Fl_Label const*, int, int, int, int, unsigned int) (in /usr/lib/libfltk.so.1.3.7)
==14238== by 0x4B3390A: Fl_Widget::draw_label(int, int, int, int, unsigned int) const (in /usr/lib/libfltk.so.1.3.7)
==14238== by 0x4AD8D70: Fl_Group::draw_child(Fl_Widget&) const (in /usr/lib/libfltk.so.1.3.7)
==14238== by 0x4AD8F92: Fl_Group::draw_children() (in /usr/lib/libfltk.so.1.3.7)
==14238==
==14238== LEAK SUMMARY:
==14238== definitely lost: 1,024 bytes in 2 blocks
==14238== indirectly lost: 1,925 bytes in 69 blocks
==14238== possibly lost: 240 bytes in 3 blocks
==14238== still reachable: 1,152,856 bytes in 11,416 blocks
==14238== suppressed: 0 bytes in 0 blocks
==14238== Reachable blocks (those to which a pointer was found) are not shown.
==14238== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==14238==
==14238== For lists of detected and suppressed errors, rerun with: -s
==14238== ERROR SUMMARY: 7 errors from 7 contexts (suppressed: 1 from 1)
Segmentation fault (core dumped)
至少可以说,这种修改只会使情况恶化 XD。
事实上,(如果我没记错的话)“映射区域的错误权限...”暗示已尝试释放内存两次,这表明fltk中确实存在一些内存管理机制。
但后来我发现了这个:
How to fix memory leaks in simplest FLTK programm?
这意味着我应该删除指针,所以现在我感到有些困惑:)
我最好的猜测是:
(1) 字体库出现故障和
(2) FLTK 有一些内部垃圾收集器(所以我不应该手动删除小部件指针以免引起任何错误),有人可以确认吗?
【问题讨论】:
标签: c++ memory-leaks fltk