草庐IT

c++ - 在 C++ 中,类函数放在内存的哪个位置?

coder 2023-06-01 原文

我试图了解通过创建大量对象会导致什么样的内存损失。我知道每个对象 - 在创建时 - 将在 HEAP 中为成员变量分配空间,并且我认为属于该类型对象的每个函数的所有代码都存在于内存中的代码段中 - 永久存在。

是吗?

因此,如果我在 C++ 中创建 100 个对象,我可以估计对象拥有的所有成员变量乘以 100(此处可能存在对齐问题)需要空间,然后我需要空间在代码段中为该类型对象的每个成员函数提供一个代码拷贝(不是 100 个代码拷贝)。

虚函数、多态性、继承因素会以某种方式影响到这个吗?

动态链接库中的对象呢?我假设 dll 有自己的堆栈、堆、代码和数据段。

简单示例(可能语法不正确):

// parent class
class Bar
{
public:
    Bar()  {};
    ~Bar() {};

    // pure virtual function
    virtual void doSomething() = 0;

protected:
    // a protected variable
    int mProtectedVar;
}

// our object class that we'll create multiple instances of
class Foo : public Bar
{
public:
    Foo()  {};
    ~Foo() {};

    // implement pure virtual function
    void doSomething()          { mPrivate = 0; }

    // a couple public functions
    int getPrivateVar()         { return mPrivate; }
    void setPrivateVar(int v)   { mPrivate = v; }

    // a couple public variables
    int mPublicVar;
    char mPublicVar2;

private:
    // a couple private variables
    int mPrivate;
    char mPrivateVar2;        
}

大约 100 个动态分配的 Foo 类型对象应该占用多少内存,包括代码和所有变量的空间?

最佳答案

“每个对象 - 在创建时 - 将在 HEAP 中为成员变量分配空间”不一定是真的。您创建的每个对象都会在某处为其成员变量占用一些非零空间,但在哪里取决于您如何分配对象本身。如果对象具有自动(堆栈)分配,那么它的数据成员也是如此。如果对象是在空闲存储(堆)上分配的,那么它的数据成员也是如此。毕竟,除了数据成员之外,对象的分配是什么?

如果堆栈分配的对象包含一个指针或其他类型,然后用于在堆上分配,则无论对象本身是在哪里创建的,该分配都将在堆上进行。

对于具有虚函数的对象,每个对象都将分配一个 vtable 指针,就好像它是类中显式声明的数据成员一样。

至于成员函数,就其在可执行镜像中的位置而言,它们的代码可能与自由函数代码没有什么不同。毕竟,成员函数基本上是一个自由函数,它的第一个参数是隐含的“this”指针。

继承不会改变任何事情。

我不确定您所说的 DLL 拥有自己的堆栈是什么意思。 DLL 不是程序,并且不需要堆栈(或堆),因为它分配的对象总是在具有自己的堆栈和堆的程序的上下文中分配。 DLL 中有代码(文本)和数据段确实是有道理的,尽管我不是在 Windows 上实现这些东西的专家(我假设你正在使用你的术语)。

关于c++ - 在 C++ 中,类函数放在内存的哪个位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/648647/

有关c++ - 在 C++ 中,类函数放在内存的哪个位置?的更多相关文章

  1. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  2. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  3. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  4. ruby-on-rails - 在 ruby​​ 中使用 gsub 函数替换单词 - 2

    我正在尝试用ruby​​中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了

  5. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  6. ruby-on-rails - Ruby 中的内存模型 - 2

    ruby如何管理内存。例如:如果我们在执行过程中采用C程序,则以下是内存模型。类似于这个ruby如何处理内存。C:__________________|||stack|||------------------||||------------------|||||Heap|||||__________________|||data|__________________|text|__________________Ruby:? 最佳答案 Ruby中没有“内存”这样的东西。Class#allocate分配一个对象并返回该对象。这就是程序

  7. ruby - 在 Ruby 中按名称传递函数 - 2

    如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只

  8. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  9. C51单片机——实现用独立按键控制LED亮灭(调用函数篇) - 2

    说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时

  10. ruby - 正则表达式在哪个位置失败? - 2

    我需要一个非常简单的字符串验证器来显示第一个符号与所需格式不对应的位置。我想使用正则表达式,但在这种情况下,我必须找到与表达式相对应的字符串停止的位置,但我找不到可以做到这一点的方法。(这一定是一种相当简单的方法……也许没有?)例如,如果我有正则表达式:/^Q+E+R+$/带字符串:"QQQQEEE2ER"期望的结果应该是7 最佳答案 一个想法:你可以做的是标记你的模式并用可选的嵌套捕获组编写它:^(Q+(E+(R+($)?)?)?)?然后你只需要计算你获得的捕获组的数量就可以知道正则表达式引擎在模式中停止的位置,你可以确定匹配结束

随机推荐