c++ 为什么内存泄漏大小大于分配给该项的内存大小?

0x6upsns  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(115)

我有以下程序:

#include <iostream>
using namespace std;

typedef struct Resource{
    int fee;  // 4 bytes
};

class MyClass {
    public:
    MyClass( string teacher, Resource * res ) : 
    teacher_(teacher),
    res_(res) { }
     ~MyClass() { 
        // delete res_; // cause indirect leak
    }  
    private:
    string teacher_;
    Resource * res_;
};

int main(){
    Resource * res = new Resource;
    res->fee=100;
    cout<<"size of Resource "<<sizeof(res)<<endl;
    MyClass * cl = new MyClass("Tom", res);  
    cl = new MyClass ("Joh", res);
    cout<<"size of My Class "<<sizeof(cl)<<endl;
    delete cl;
}

字符串
Address Sanitizer返回以下错误:

size of Resource 8
size of My Class 8
Program stderr

=================================================================
==1==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 40 byte(s) in 1 object(s) allocated from:
    #0 0x7f863ac55518 in operator new(unsigned long) (/opt/compiler-explorer/gcc-13.2.0/lib64/libasan.so.8+0xdb518) (BuildId: 5ce9c09d3612315d01d50bcaafaea176e7ddab77)
    #1 0x402445 in main /app/example.cpp:25
    #2 0x7f863a5d3082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082) (BuildId: 1878e6b475720c7c51969e69ab2d276fae6d1dee)

Indirect leak of 4 byte(s) in 1 object(s) allocated from:
    #0 0x7f863ac55518 in operator new(unsigned long) (/opt/compiler-explorer/gcc-13.2.0/lib64/libasan.so.8+0xdb518) (BuildId: 5ce9c09d3612315d01d50bcaafaea176e7ddab77)
    #1 0x4023c4 in main /app/example.cpp:22
    #2 0x7f863a5d3082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082) (BuildId: 1878e6b475720c7c51969e69ab2d276fae6d1dee)

SUMMARY: AddressSanitizer: 44 byte(s) leaked in 2 allocation(s).

*indirect leak的大小为4 bytes,我认为这是分配给结构体Resource的int值的内存块。
*direct leak大小为40 bytes,大小不是MyClass(8)和struct Resource(8)之和。

为什么直接泄漏这么大?

7cjasjjr

7cjasjjr1#

你对sizeof的理解是错误的。cl是一个指针,sizeof(cl)是指针的大小,在大多数64位平台上是8字节。你应该使用sizeof(MyClass)sizeof(*cl)来获取对象的大小。
MyClass有两个数据成员,通常在gcc实现中,std::string的短字符串开销为32字节(您可以搜索short string optimization了解更多细节),而Resource *的开销为8字节。因此,sizeof(MyClass)为40字节,这是直接泄漏大小。

相关问题