![]() |
Здравствуйте, гость ( Вход | Регистрация )
![]() ![]() |
![]() |
rp80 |
![]()
Сообщение
#1
|
Студент ![]() Группа: Участник Сообщений: 36 Регистрация: 10.9.2011 Пользователь №: 2860 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Есть такой код.
2 вопроса: 1. Правильны ли следующие рассуждения относительно первых двух объявлений str_copy? В первом случае указатель объявлен, но еще не инициализирован, т.е. фактически никуда не указывает ещё, поэтому и обращения к нему некорректны. Во втором случае str_copy объявлена как строковый литерал, т.е. как const char[2] и во-первых изменять значения такого массива нельзя, а во-вторых указатель выходит за рамки массива после 2. 2. Почему работает последний вариант? Ведь по идее надо бы выделить память следующим образом char* str_copy=new char[strlen(str)]; Спасибо. |
|
|
Алексей1153 |
![]()
Сообщение
#2
|
![]() фрилансер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 2943 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: ![]() ![]() ![]() |
rp80,
а зачем вот это чудо тут ?
а почему работает копирование в константу - это чистая случайность Цитата char* str_copy=new char[1];//Работает тоже до поры до времени. Нет терминатора! Сообщение отредактировал Алексей1153 - 4.11.2011, 9:45 |
|
|
rp80 |
![]()
Сообщение
#3
|
Студент ![]() Группа: Участник Сообщений: 36 Регистрация: 10.9.2011 Пользователь №: 2860 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
rp80, а зачем вот это чудо тут ?
Это не пиип, а пример expression-oriented coding из Страуструпа. Функция работает так как и задумано. а почему работает копирование в константу - это чистая случайность Цитата char* str_copy=new char[1];//Работает тоже до поры до времени. Нет терминатора! char* str_copy=new char[1] - не константа далеко. И терминатор в этой строке не нужен, потому что в нее копируем а не из нее. Я уже в общем понял почему так происходит.. Хоть память выделена и под 1 чар, но за этим сегментом есть какие-то следующие, поэтому q++ существует и туда можно записать. Но память все равно нужно выделять под весь массив, ибо иначе мы можем залезть в память , выделенную под другие объекты. |
|
|
BRE |
![]()
Сообщение
#4
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: ![]() ![]() ![]() |
В первом случае указатель не инициализирован и может содержать любой адрес, так что первый случай может и падать и не падать. Как повезет.
![]() Во втором случае, указатель указывает на сегмент данных, запись в который может быть запрещена. Поэтому падает. В третьем случае не падает сразу. Но возможно падение потом, причем трудно обнаруживаемое. Т.к. возможно разрушение управляющих структур кучи. |
|
|
Алексей1153 |
![]()
Сообщение
#5
|
![]() фрилансер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 2943 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: ![]() ![]() ![]() |
rp80, ну что ж, успехов )
Цитата char* str_copy=new char[1] - не константа далеко. И терминатор в этой строке не нужен, потому что в нее копируем а не из нее. это не константа, я не про эту строку говорил ![]() а вот нечитаемое это безобразие Цитата while(*p++=*q++); надлежит заменять на человеческий код
Сообщение отредактировал Алексей1153 - 4.11.2011, 18:56 |
|
|
rp80 |
![]()
Сообщение
#6
|
Студент ![]() Группа: Участник Сообщений: 36 Регистрация: 10.9.2011 Пользователь №: 2860 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
И ещё пара вопросов тут напишу, чтоб темы не плодить.
1. Корректно ли следующее освобождение памяти?
2. Здесь имеет место Placement new и неважно чар буффер или инт, главное выделить достаточно памяти?
Спасибо. |
|
|
BRE |
![]()
Сообщение
#7
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: ![]() ![]() ![]() |
а вот нечитаемое это безобразие Цитата while(*p++=*q++); Вообще это обычный strcpy. надлежит заменять на человеческий код
В первый проход вычисляем длину строки, а во второй ее копируем? Не много ли проходов? strcpy и вышеприведенная функция делает все в один проход. ![]() 1. Корректно ли следующее освобождение памяти? Нет. Это попытка освободить память на стеке. ![]() главное выделить достаточно памяти? Да. А там хоть: float arr[ 100 ]; ![]() Кстати, такая конструкция чревата утечками памяти:
Здесь ты переменной i2 присваиваешь значение из безымянной переменной, которая создается на куче. Дальше указатель на эту переменную теряется... ну и соответственно память не освобождается. Сообщение отредактировал BRE - 4.11.2011, 22:30 |
|
|
Алексей1153 |
![]()
Сообщение
#8
|
![]() фрилансер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 2943 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: ![]() ![]() ![]() |
BRE, неважно, что там два прохода. Зато читаемость
![]() Вот когда тесты показали, что скорости недостаточно, а профайлер ткнул пальцем в это место, тогда будем мудрить. А кроме того, предлагаю сделать тестик и замерить скорость выполнения обоими способами - не факт, что мой будет медленнее ![]() Сообщение отредактировал Алексей1153 - 4.11.2011, 21:51 |
|
|
BRE |
![]()
Сообщение
#9
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: ![]() ![]() ![]() |
BRE, неважно, что там два прохода. Зато читаемость ![]() Читаемость лучше? Здесь?
И чем это ближе к ООП, по сравнению с strcpy? ![]() |
|
|
Алексей1153 |
![]()
Сообщение
#10
|
![]() фрилансер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 2943 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: ![]() ![]() ![]() |
читаемость конечно лучше. И ещё лучше, если заменить на strcpy , но лично я им не пользуюсь, не предоставлялось случаев ) Я обычно для строк использую std::string, std::wstring , а когда надо с отдельными литерами работать - предпочитаю контролировать каждый байтик (а я навскидку не помню, как strcpy обрабатывает терминатор - копирует его тоже или нет)
|
|
|
![]() ![]() ![]() |
![]() |
|
Текстовая версия | Сейчас: 23.6.2025, 14:11 |