Как я могу найти адрес строкового литерала?
Предположим, у меня есть следующее:
char *a = "Learning CPP";
char *b = "Learning CPP";
Могу ли я сказать, что общая используемая память была sizeof (a), а не 2*sizeof (stringliteral)?
Потому что мое понимание строковых литералов состоит в том, что хранится одна копия строки. Но, как бы то ни было,
Разве он не хранится между адресами a, a + 1, a + 2..... a + 12 в памяти, а также b, b + 1, b + 2... b + 12 в памяти (12 - это sizeof строка)?
4 ответа
Как я могу найти адрес строкового литерала?
Вы нашли адрес строкового литерала. Значением строкового литерала является адрес его первого символа. Вы присвоили это значение a
а также b
,
Могу ли я сказать, что общая используемая память была sizeof (a), а не 2*sizeof (a)?
Прежде всего вопрос искажен. sizeof(a)
это размер указателя.
Вы намеревались спросить:
Могу ли я сказать, что общий объем памяти, используемый для строковых литералов, равен размеру, необходимому для одной копии строки, а не размеру, необходимому для двух копий строки?
Нет, это деталь реализации компилятора. Он может выбрать для интернирования строк или не по своей прихоти. Если вы изменяете одну из строк, это определяется реализацией, если другая строка считается измененной.
Это является следствием более общего факта, что если вы изменяете одну из строк, то это определяется реализацией, то есть точка. Все может случиться.
мое понимание строковых литералов заключается в том, что хранится одна копия строки.
Ваше понимание ошибочно. Это не гарантия языка. Это оптимизация, которую может выбрать компилятор или нет.
Разве он не хранится между адресами a, a+1, a+2 ..... a + 12 в памяти, а также b, b + 1, b + 2 ... b + 12 в памяти (12 - это sizeof строка)?
Я не могу понять этот вопрос. Что такое "это", которое не сохраняется?
Следующий код покажет вам, где переменные и где строки
printf( "variable a is at address %p\n", &a );
printf( "variable b is at address %p\n", &b );
printf( "the string that a points to is at address %p\n", a );
printf( "the string that b points to is at address %p\n", b );
Обратите внимание, что последние две строки могут или не могут печатать один и тот же адрес, в зависимости от компилятора. Не требуется, чтобы компилятор создавал только одну строку.
Вы можете проверить это сами. Например
if ( a == b ) std::cout << "The string literals are coinside" << std::endl;
else std::cout << "The string literals occupy different areas of memory" << std::endl;
Обычно компиляторы имеют опции, позволяющие контролировать, будут ли два одинаковых строковых литерала занимать одну и ту же память, или каждый литерал будет размещен в своей области памяти.
Могу ли я сказать, что общая используемая память была sizeof (a), а не 2*sizeof (a)? -> Нет, sizeof (a) это sizeof(char *) = 4
Разве он не хранится между адресами a, a + 1, a + 2..... a + 12 в памяти, а также b, b + 1, b + 2... b + 12 в памяти (12 - это sizeof строка)? -> Используя компилятор gcc, когда строки равны, a и b имеют один и тот же адрес. Когда строки разные, я нахожу разные а и б разные адреса. (эй, это было забавное упражнение.. я узнал что-то новое)
#include <stdio.h>
#include <iostream>
using namespace std;
int main()
{
char const* p ="Hello";
printf("%d",p); //prints the address of the first byte. ie of 'H'
cout<<p[0] // prints H
cout<<p[1] //prints e
}
Вы можете сделать это на C или C++, чтобы определить адрес строкового литерала.