Как мне найти адрес памяти строки? - PullRequest
3 голосов
/ 12 июля 2011

У меня ментальный блок, и я знаю, что должен это знать, но мне нужна небольшая помощь.

Если я объявлю строковую переменную следующим образом:

    string word = "Hello";

Как мненайти адрес памяти "Hello"?

Редактировать: это то, что я пытаюсь сделать ...

Написать функцию, которая принимает один аргумент, адрес строкии печатает эту строку один раз.(Примечание. Для завершения этой части вам понадобится указатель.)

Однако, если указан второй аргумент типа int и он не равен нулю, функция должна напечатать строку несколько раз, равнуюколичество раз, которое функция была вызвана в тот момент.(Обратите внимание, что число раз, которое строка печатается, не равно значению второго аргумента; оно равно числу раз, которое функция была вызвана до сих пор.)

Ответы [ 6 ]

9 голосов
/ 12 июля 2011

Используйте:

  • std::string::data(), если ваши данные не заканчиваются на ноль, как.

или

  • std::string::c_str(), если вы хотите получить данные и гарантированно получите нулевое завершение.

Обратите внимание, что указатель возвращается любым из этих вызовов не должен быть базовыми данными, которыми манипулирует объект std::string.

5 голосов
/ 12 июля 2011

Взять адрес первого символа обычным способом сделать это.&word[0].Однако необходимость делать это, если вы не работаете с устаревшим кодом, обычно является признаком того, что вы что-то делаете неправильно.

2 голосов
/ 12 июля 2011

Вы можете использовать функцию c_str(), чтобы получить указатель на строку C (const char *);однако обратите внимание, что указатель становится недействительным всякий раз, когда вы изменяете строку;Вы должны снова вызвать c_str(), поскольку старая строка могла быть освобождена.

2 голосов
/ 12 июля 2011

Полагаю, вы хотите указатель на простую старую C-строку? Затем используйте word.c_str(). Обратите внимание, что это не гарантирует указание на внутреннее хранилище строки, это просто (постоянная) версия C-строки, с которой вы можете работать.

0 голосов
/ 02 июля 2017

ОК, я знаю, что этот вопрос старый, но мне кажется, что очевидный ответ здесь на самом деле:

std::string your_string{"Hello"};

//Take the address of the beginning
auto start_address = &(*your_string.begin())

//Take the address at the end
auto end_address = &(*your_string.end())

По сути, это будет выполнять то же самое, что и использование:

auto start_address = your_string.c_str();

auto end_address = your_string.c_str() + strlen(your_string.c_str());

Однако я бы предпочел первый подход (с использованием адреса разыменованного итератора), потому что:

a) Гарантируется работа с начальными / конечными совместимыми контейнерами, которые могут не иметь метода c_str. Так, например, если вы решили, что хотите, чтобы QString (использовалась строка QT) или AWS :: String или std :: vector содержали ваши символы, подход c_str () не сработает, но тот, который приведен выше, будет.

b) Возможно, не так дорого, как c_str () ... который, вообще говоря, должен быть реализован аналогично вызову, который я сделал во второй строке кода, чтобы получить адрес, но не гарантированно будет реализован таким образом (например, если используемая вами строка не заканчивается нулем, для добавления нулевого терминатора может потребоваться перераспределение и мутация всей строки ... что внезапно сделает ее поток небезопасным и очень дорогостоящим, это не относится к std: : строка, но может быть для других типов строк)

c) Он лучше передает намерение, в конце концов, вам нужен адрес, и первая группа кода выражает именно это.

Так что я бы сказал, что этот подход лучше для:

Ясность, совместимость и эффективность.

Edit:

Обратите внимание, что при любом подходе, если вы измените свою исходную строку после получения адреса, адрес будет признан недействительным (поскольку строка может быть перемещена). Компилятор не предупредит вас об этом, и это может привести к очень неприятным ошибкам: /

0 голосов
/ 12 июля 2011

Объявите указатель на переменную и затем просмотрите его, как вы бы.

...