C ++ понимание хранения строк - PullRequest
0 голосов
/ 28 января 2020

Я довольно новичок в программировании на C ++ и хочу по-настоящему понять, что я делаю, прежде чем продолжить обучение.

У меня есть следующий код

int main()
{
    std::string myWord = "something";

    std::cout << "'myWord' address => " << &myWord << std::endl;
    std::cout << "myWord's capacity => " << myWord.capacity() << std::endl;

    return 0;
}

, который дает мне

'myWord' address => 004FF930
myWord's capacity => 15

Когда я смотрю на вкладку памяти Visual Studio, я получил это:

enter image description here

Итак, во-первых, почему содержание 004FF930 не равно " s " (тогда -> o, m, e, t , h, i, n, g, \ 0)?
Я предполагаю, что первый выделенный размер для моей строки имеет длину 15 байт (значение, возвращаемое capaticy()). Если я прав, я не понимаю, почему число байтов от 004FF930 до \ 0 char составляет всего 14, а не 15?

Теперь, если я увеличу myWord длина более 15, как это:

int main()
{
    std::string myWord = "something longer";

    std::cout << "'myWord' address => " << &myWord << std::endl;
    std::cout << "myWord's capacity => " << myWord.capacity() << std::endl;
}

Теперь это дает мне

'myWord' address => 00B5F6DC
myWord's capacity => 31

Я снова смотрю на вкладке памяти

enter image description here

На данный момент у меня нет никаких предположений, потому что я просто не понимаю ... Где моя строка ???

Ответы [ 2 ]

1 голос
/ 28 января 2020

std::string - это больше, чем последовательность символов. Очень упрощенно это

struct OversimplifiedString {
    size_t capacity;
    size_t size;
    char* data;
};

Чтобы получить массив символов (точнее указатель на первый символ) из std::string s, вы можете использовать s.data(), s.c_str() или &s[0] .

1 голос
/ 28 января 2020

Указатель, который вы видите, - это не сами строковые данные, а память, которая является экземпляром строкового класса - который, вероятно, внутренне содержит указатель на данные, которые размещены вне самого класса (но принадлежат и управляются учебный класс). Это то, что вы видите во втором результате.

Опционально, строки могут выполнять то, что называется оптимизация небольших строк , где строковые данные хранятся внутри самого класса. Так как класс строки имеет фиксированный размер, вы можете хранить в нем только небольшие строки - все, что больше, будет go как внешние данные, как в первом пункте выше. Это то, что вы видите в своем первом результате.

Чтобы получить доступ к базовым данным для строки, используйте myWord.data () или & myWord [0]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...