Другие языки программирования и технологии

Указатели на строки в C++

Здравствуйте! Я изучаю С++ и сейчас не могу найти нигде ответа на следующий вопрос.

Допустим, я объявляю два указателя на строки и инициализирую их строковыми литералами:

char* ololo = "blablabla";
char* ololo2 = "kkk";

Тогда память под эти строки выделяется еще на этапе компиляции. Если я напишу такую строку:
ololo = ololo2;

то строка, на которую указывал ololo будет потеряна. Но будет ли память, занимаемая ей очищена? Или так лучше не делать, поскольку это по сути утечка памяти?

И еще один вопрос.

Могу ли я написать так?
ololo = "gggggggggggggggg";

Эксперимент показал, что могу. Но откуда берется память под этот gggggggggggggggg? Ведь программа должна куда-то записать эту строку.

Возможно сначала нужно выделить память под этот gggggggggggggggg?
ololo = new char [17];

Спасибо заранее за ответы.
1) да, будет отчищена
2) точно так же выделяется на стеке при компиляции
3) можно и выделить, но надо не забыть удалить

объясню
char* ololo = "blablabla";
сначала выделяется память под "blablabla", а потом указатель на нее присваивается ololo. поэтому вариант с
ololo = "gggggggggggggggg";
работает
Karim *****
Karim *****
38 457
Лучший ответ
Кирилл Перетятько Все понятно! Значит blablabla и gggggggggggggggg размещаются в стеке, а не в динамической памяти, точно))

Благодарю!)

А этот код вызывает ошибку, если я правильно понял, потому что функции работы со строками не выделяют никакой памяти?

То есть тут: ololo = "gggggggggggggggg" сначала память выделяется в стеке, а потом адрес первого элемента присваивается ololo.

а тут:
char* ololo = "blablabla";
char* ololo2 = "iii";
strcpy(ololo, ololo2);

strcpy ничего не выделяет, а пытается записать результат своей работы по адресу ololo. а ololo указывает на место, куда запись во время программы невозможно.

правильно я понимаю?
НЕТ
Строки-Константы хранятся отдельно и подгружаются в память при загрузке файла на исполнение
Даже если использовать
string a=new("qqqqqqqqqqq"); создается экземпляр класса string, выделяется память и в эту память копируется содержимое константы "qqqqqqqqqqq", сама костанта НИКУДА не исчезает
Кстати умные компиляторы могут и не заметить такой финт
char *a="ABCDDD";
char *b="DDD";
//На этом месте НИКТО не гарантирует, что компилятор для уменьшения объема констант не "склеил" строки
a[4]='Y';
Вполне может оказаться, что теперь b[1]=='Y'
Поэтому правильный способ выглядит так
char a[]="ABCDDD";
char b[]="DDD";
Выделяем память под массив и заполняем его значениями
a[4]='Y' - никак не повлияет на b[1]

Нормальная программа
int main()
{
char ololo[] = "blablabla";
char ololo2[] = "iii";
cout << ololo << endl;
cout << ololo2 << endl;
strcpy(ololo, ololo2);
cout << ololo << endl;
return 0;
}
Аварийная программа
int main()
{
char *ololo = "blablabla";
char *ololo2 = "iii";
cout << ololo << endl;
cout << ololo2 << endl;
strcpy(ololo, ololo2);
cout << ololo << endl;
return 0;
}
Dmitriy Zholkovskiy
Dmitriy Zholkovskiy
71 180
Кирилл Перетятько мм.. не до конца понял, честно говоря

вначале был ответ на мой первый вопрос? то есть когда я перенаправляю указатель ololo на что-то другое, выходит, что константа, на которую он раньше указывал, так и будет висеть в памяти?

в общем мораль в том, что лучше вообще не использовать такую форму записи?
char* ololo = "blablabla";

и использовать только форму записи в виде массива?
нужно хорошо понимать где размещаются строки и что просходит при strcpy
при записи char* ololo = "blablabla"; строка может быть размещена в "read only"
и при попытке записи *ololo='a' возникнет ошибка
strcpy может не проверяет длину выходной строки и может затереть данные -- потом долго искать ошибку
компилятор может "склеивать" одинаковые строки тогда запись в одну строку приведет к порче другой
char *ptr1="abc";
char *ptr2="abc";
*ptr1='b';
printf(ptr2); -- может вывести не abc a bbc