Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我不知道';无法理解追加字符串的内存问题_C++ - Fatal编程技术网

C++ 我不知道';无法理解追加字符串的内存问题

C++ 我不知道';无法理解追加字符串的内存问题,c++,C++,在该链接的第一个答案中,它说在字符串中添加字符会导致内存问题 string s=”“; 字符c='a'; int max=int_max; 对于(int j=0;j 我不明白为什么代码会反复复制相同的字符串 再说一遍 好的,让我们看看循环每次迭代时会发生什么: s = s + c; 为了执行这行代码,程序必须做三件事: 计算临时值s+c——为此,程序必须创建一个临时的匿名std::string对象,并(从堆中)为其分配一个内部字节缓冲区,该缓冲区至少比s中当前的字符数大一个字节(这样它就可以保

在该链接的第一个答案中,它说在字符串中添加字符会导致内存问题

string s=”“;
字符c='a';
int max=int_max;
对于(int j=0;j
我不明白为什么代码会反复复制相同的字符串
再说一遍

好的,让我们看看循环每次迭代时会发生什么:

s = s + c;
为了执行这行代码,程序必须做三件事:

  • 计算临时值
    s+c
    ——为此,程序必须创建一个临时的匿名
    std::string
    对象,并(从堆中)为其分配一个内部字节缓冲区,该缓冲区至少比
    s
    中当前的字符数大一个字节(这样它就可以保存所有
    s
    的旧内容,以及
    c
    提供的附加字符)

  • s
    设置为等于临时字符串。在C++03和更早版本中,这可以通过将
    s
    的内部字节缓冲区重新分配为更大,然后将临时字符串中的所有字节复制到
    s
    的新的/更大的缓冲区中来完成。C++11通过new move assignment操作符对此进行了一点优化,以便所有bytes不必被复制;相反,
    s
    可以简单地拥有临时字符串的字节缓冲区

  • 释放临时字符串的资源,现在我们已经使用它了。实际上,这采取了
    std::string
    类的析构函数的形式,在旧的(不再足够大的)字节缓冲区上调用
    delete[]

  • 考虑到上述操作在一个循环中至少要执行20亿次,它已经相当低效了

    但是,我认为您提到的答案特别关注的是堆碎片。请记住,堆分配不是靠魔法实现的;当您(或
    std::string
    类,或任何人)请求从堆中分配N字节的内存,堆实现的任务是找到N字节的连续内存并返回它。而且由于C++中没有提供用于移动内存块的规定(这样做会使程序可能指向内存块的指针无效)。,堆不能用较小的内存块创建一个N字节的连续内存块;相反,必须有一系列的连续内存空间可用。例如,如果1GB内存由数千个非连续的1KB内存块组成,并且调用者请求2KB分配

    因此,堆的任务是有效地分配程序请求大小的内存块,当它们再次被释放时,它会尝试将它们重新粘合到更大的内存块中(如果可能的话),但它可能并不总是能够。某些分配和释放内存的模式可能会导致堆碎片,这很简单大量不连续的内存分配,使得它们之间的小的空闲内存区域无法用于大的分配


    我不确定这种特定的分配/释放模式是否会导致这种情况;考虑到一次只分配一个或两个缓冲区,当它们再次被释放时,堆可能能够将它们重新吸收回相邻的空闲内存块中——这可能取决于系统使用的特定堆算法,以及whet在这过程中,任何其他线程都在分配/释放堆内存。但如果有系统会导致问题(特别是在虚拟地址空间有限的16位或32位系统上,或者不使用虚拟内存的嵌入式系统上),我也不会太惊讶

    你的电脑有多少RAM?INT_MAX的值是多少?在许多语言中,字符串是不可变的,这意味着每次你想从另外两个字符串中创建一个字符串时,你必须获取一个新字符串来保存结果。在循环的每次迭代中,字符串比以前长一个字符。同样,在lo的每个副本上op,创建一个长度为(j+1)的临时字符串,然后复制数据(或在c++11中,移动)从临时字符串返回到代码> S>代码>我的RAM有8 GB。当我添加CHILITH头文件<代码>包含< /C> >时,我可以使用const value <代码> INTXMAX,这意味着int类型在C++中可以拥有最大值。@ HuggYuKIM可以提供一个吗?因为内存问题很大程度上依赖于平台。撤销回答中的语句:“字符串所需的重复重新分配可能会导致内存管理器中出现碎片,并导致更快的内存不足问题”必须复制字符串,因此需要分配内存。太棒了!!你的解释就是我在学校学的。但我不完全理解堆碎片为什么如此重要。衷心感谢你的仔细评论!!