c – std:string如何阻止我不小心踩到它的数据?

前端之家收集整理的这篇文章主要介绍了c – std:string如何阻止我不小心踩到它的数据?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有以下C代码
#include <string>
#include <iostream>


int main(int argc,char** argv)
{
    int size;
    std::string strArray[3];
    std::string str0 = "String 0";
    std::string str1 = "String 1";
    std::string str2 = "String 2";

    strArray[0] = str0;
    strArray[1] = str1;
    strArray[2] = str2;

    for (int i = 0; i < 3; i++)
    {
        std::cout << strArray[i] << std::endl;
    }

    str1.resize(200,'a');

    for (int i = 0; i < 3; i++)
    {
        std::cout << strArray[i] << std::endl;
    }

    std::cout << str1 << std::endl;

    std::cin.get();
    return 0;
}

这里的想法是我有一个数组,它是一个连续的内存块,其中每个成员都是一个std :: string,它是可变的,因此大小可变.我期望这段代码能够破解,因为我调整str1的大小来占用比原来更多的空间,因此“溢出”到str2中.

相反,我得到这个输出

String0

String1中

字符串2

String0

String1中

字符串2

String1aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa …

我有两个问题.首先,如何增加str1的大小并向其添加大量字符不会流入str2,即使它们应该位于连续的内存块中?

第二,为什么在调整str1大小后第二次打印数组并向其添加字符时,它仍会打印原始的str1?
我有一种感觉,这将与我的第一个问题的答案有关,但我不能完全看到这里发生了什么.

解决方法

字符串对象数组是连续的,但实际的字符串数据存储在堆*上,因此字符串数据本身不会连续存储.

*实际上给定一个使用“小字符串优化”的实现,数据是连续的,只要它足够小就可以存储在字符串对象中. ‘String0’足够小,适用于我所知道的所有SSO实现.一旦数据增长超过可以就地存储的内容,实现就会将其移动到堆上.

修改str1不会影响打印strArray [1]的结果的原因是它们是没有关系的不同对象,除了用str1的值初始化strArray [1].这就像做:

int intArray[3];
int int0 = 0;
int int1 = 1;
int int2 = 2;

intArray[0] = int0;
intArray[1] = int1;
intArray[2] = int2;

int1 = 10000000; // does not modify intArray[1]

这里的想法是C中对象的通常行为与您在其他语言中可能熟悉的“原始类型”或“值类型”相同.可以在C中实现其他行为,但std :: string是常规类型.

猜你在找的C&C++相关文章