【问题标题】:Memory location for virtual functions虚函数的内存位置
【发布时间】:2015-04-17 01:37:52
【问题描述】:

假设我有 base.h 类

#ifndef BASE_H
#define BASE_H

class base
{
public:
    base(){}
    virtual void id() const{ std::cout << "base\n"; }
    virtual ~base(){}
protected:
private:
};

#endif // BASE_H

以及派生的.h 类

#ifndef DERIVED_H
#define DERIVED_H

#include <base.h>

class derived : public base
{
public:
    derived(){}
    void id() const{ std::cout << "derived\n"; }
protected:
private:
};

#endif // DERIVED_H

我开始在主代码中测试不同的结果

int main()
{
    base* bas;
    derived* der;
    base statbas;
    derived statder;

    *bas = statbas;   // here it crashes

    bas = new base;   

    *bas=statbas;     // here it works. It also worked with bas=&statbas;

    bas->id();

    return 0;
}

看来我需要为指针bas分配一些内存,否则程序会崩溃。这件事让我很困惑,主要是因为我无法想象为没有任何变量的对象(在这种情况下为bas)存储内存(类库仅由函数形成)。

另一件事让我感到困惑,显然*bas=statbas(bas 指向 statbas)和bas=&amp;statbas(bas 具有 statbas 的内存地址)不相等,实际上第一个使程序崩溃,而第二个工作.

我假设所有这些问题都与基类中的虚拟函数有关,事实上,当 id() 未声明为虚拟时,程序不会崩溃(但显然也无法正常工作)。

有人可以澄清一下在这种情况下如何管理内存吗?

【问题讨论】:

  • 您的问题与虚函数有关。确保您首先了解指针的工作原理。
  • 并且以防万一您弄错了“静态”变量是什么(我从变量名猜测)。在函数范围内声明的变量不是静态的
  • 我知道静态变量是其他东西,我只需要一个名字

标签: c++ inheritance memory-management virtual


【解决方案1】:
*bas = statbas;   // here it crashes

因为您取消引用未初始化的 bas,因此您会得到未定义的行为。

bas = new base;
*bas=statbas;     // here it works. It also worked with bas=&statbas;

之所以有效,是因为bas 已在前一行初始化并指向内存中的有效对象。bas=&amp;statbas 做了其他事情。它分配bas 指向另一个对象,导致新分配的对象泄漏,因为它不再被任何东西指向,因此永远不能被删除。

看来我需要为指针bas分配一些内存,否则程序会崩溃。

正确。

这件事让我很困惑,主要是因为我无法想象为没有任何变量(类库仅由函数形成)的对象(在本例中为 bas)存储内存。

您可以为没有成员的对象分配内存,就像为有成员的对象分配内存一样。

另一件事让我感到困惑,显然 *bas=statbas(bas 指向 statbas)和 bas=&statbas(bas 具有 statbas 的内存地址)不相等,实际上第一个使程序崩溃,而第二个有效。

这不是第一个所做的。第一个取消引用bas,然后将statbas 复制到取消引用的对象。第二个设置bas 指向statbas

我假设所有这些问题都与基类中的虚拟函数有关,实际上,当 id 未声明为虚拟时,程序不会崩溃(但显然也无法正常工作)。

不,问题与虚拟功能没有真正的联系。您只需取消引用未初始化的指针。虚拟性恰好是幸运地导致未定义行为不同的东西。

【讨论】:

  • 当函数没有被声明为虚函数时,为什么它不会产生意外的行为?
  • 当行为未定义时,没有可以“预期”的行为。因此,任何行为都不应该是出乎意料的。
【解决方案2】:

当你取消引用一个指针时,它应该指向某个东西。你的根本没有初始化。

要使指针指向自动变量的地址,应将其地址设为bas = &amp;statbas

【讨论】:

    【解决方案3】:

    看来我需要为指针 bas 分配一些内存 否则程序会崩溃。这件事主要让我感到困惑 因为我无法想象为一个对象存储内存(基于此 案例)没有任何变量(类基只是形成 按功能)。

    当你声明一个指针时,不管它是什么类型,它最初都不指向任何地方。

    int* p;
    

    给这样的指针赋值肯定会像写一样崩溃

    int n;
    

    正在创建一个具有任意值的变量 n。

    另一件事让我感到困惑,显然 *bas=statbas (bas 指向 statbas) 和 bas=&statbas (bas 的内存地址为 statbas) 不相等,实际上第一个使程序崩溃 而第二个有效。

    如果 bas 会指向某个地方,那么

    *bas = statbase;
    

    会将 statbase 的内容复制到 bas 指向的位置,因为 bas 没有指向任何特定的地方,您会遇到崩溃。

    写作

     bas = &statbase;
    

    是有效的,因为 bas 是一个指针,您将其分配为指向“base”的实例,即statbase

    我假设所有这些问题都与功能有关 基类中的虚拟,实际上当 id 未声明为虚拟时 程序不会崩溃(但显然不能正常工作 要么)。

    你猜错了,所有这些问题都与内存管理和指针有关。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-07
      • 2015-02-09
      • 2013-06-24
      • 1970-01-01
      • 2020-09-15
      • 2015-04-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多