【问题标题】:will a class without any data member cause memory leak? [duplicate]没有任何数据成员的类会导致内存泄漏吗? [复制]
【发布时间】:2012-10-24 07:28:12
【问题描述】:

可能重复:
C++: What is the size of an object of an empty class?

如果类没有任何数据成员而只有方法,它仍然有可能发生内存泄漏。首先类方法是对类对象的引用,而对象在分配时仍然需要内存来存储地址。我说的对吗?

class Empty
{
  doA()
  {
  }
};

【问题讨论】:

    标签: c++


    【解决方案1】:

    好吧,即使是空类,sizeof 也必须大于 0,因此该类仍然会占用空间。原因是唯一的对象应该有唯一的地址。它是否具有成员函数(方法)这一事实无关紧要。

    所以这会泄漏:

    new Empty; // leaking at least 1 byte
    

    【讨论】:

    • 嗯,我想知道 - 然后你可以使用这个事实并创建一个没有数据成员的“计数器”类,但可以使用 Counter() { *((char *)this) = 0; } Counter::Incr() { *(char *)this)++; } 等方法计算多达 255 个?这会安全吗?能保证安全吗?
    • @Rollie this 是一个右值,所以你不能这样分配它。
    • 它似乎适用于 VC 2010 和 GCC 4.7。代码:pastebin.com/QmiAHfKa 作为一个暗中的镜头,也许是因为右值指针可以指向一个非右值对象,所以一旦取消引用就可以修改它
    • @Rollie 哦,我没有看到取消引用。是的,这是未定义的行为。
    【解决方案2】:

    标准要求每个类实例具有非零大小,甚至是空类。请参阅此answer 了解原因。

    标准不要求以下内容,但适用于我使用过的每个编译器(Visual C++、GCC、Clang):

    实例不存储成员函数的地址。编译器在编译/链接时已经知道每个成员函数的地址。因此,具有 100 个成员函数且只有一个 float 数据成员的类将只占用 sizeof(float) 字节空间。

    如果一个类具有虚函数,则该类的每个实例都需要存储virtual function table 指针。

    【讨论】:

    • 这仅适用于某些实现。没有什么可以阻止类存储指向其成员的指针、添加填充或不使用 vtables。
    • 我想知道哪些实现存储指向它们的成员函数的指针,这样我就可以尽可能远离它们。
    【解决方案3】:

    如果类没有任何数据成员而只有方法,它仍然有可能发生内存泄漏。

    是的,您仍然可以在该类型上泄漏内存。您可以泄漏任何类型,甚至是 没有成员的类型。 sizeof(EmptyClass) 永远不会等于 0。请参阅:http://www.stroustrup.com/#sizeof-empty

    来自规范:

    最大派生类的大小应大于零。

    【讨论】:

      【解决方案4】:

      内存中的任何对象都需要“空间”。即使是这样的空类也会自动将 Constructor 和 CopyConstructor 投入其中。所有这些都需要记忆。并且忘记delete 内存将导致恰好sizeof(Empty) 字节的内存泄漏。它是 1byte 还是几个都没有关系。

      【讨论】:

        【解决方案5】:

        这将取决于您如何分配对象,并且在大多数情况下(或所有情况),即使该类为空,如果您使用例如 newmalloc 和类似方法分配它,您如果丢失指向它的指针,就会发生内存泄漏。但这也取决于实现。

        那是因为newmalloc 都可以在对象的内存空间附近存储已分配对象的信息。

        如果您根本不使用声明的类,编译器可能会将其优化掉,因此您不会有任何内存泄漏,因为您从未为它分配内存。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-08-13
          • 2017-09-11
          • 2021-03-23
          • 2021-09-25
          • 2014-12-08
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多