![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
dAnIK SeNT |
|
|||
Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 8.2.2003 Где: Казань Репутация: нет Всего: нет |
Пишу я к примеру
char *myvar = "sdfsdf"; Очевидно, выделяется 7 байт памяти. Не должен ли я их освобождать самостоятельно? Т.е. понятно, что когда я пишу char myvar[255] = "sdfsd"; То все ок., т.к. данные размещаются в памяти статически. А вот в случае динамического размещения? Или еще пример:
Все ли я понимаю правильно? Вообще работа с указателями как-то неочевидна. Как я могу различить, когда я присваиваю значение указателю, а когда - тому на что он указывает? Скажем, у меня есть int *v; я хочу выделить под него память. как это сделать? и как ее потом освободить? допустим, я сделал это. Хочу изменить то значение на которое указывает v. Я пишу: v = 0xFFFFFF; А теперь я хочу сделать так, чтобы v указывал на участок памяти по адресу 0xFFFFFF. Как это сделать? Вопрос next. Некоторая функция возвращает мне строку, под которую она очевидно распределила память. Как мне освободить эту памть? Спасибо за внимание ![]() |
|||
|
||||
Step |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5151 Регистрация: 26.9.2002 Где: дурдом.UA Репутация: 5 Всего: 25 |
а значение *v=5; Освобождать желательно, это как правила хорошего тона. -------------------- - Дурак учится на своих ошибках, умный на чужих. - умные учатся у дураков |
|||
|
||||
Step |
|
||||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5151 Регистрация: 26.9.2002 Где: дурдом.UA Репутация: 5 Всего: 25 |
int *v; int o; v=new int; *v=5; сдесь по адрессу куда указывает v заноситься 5 o=4; v=&o; теперь v указывает на о в котором записано 4
delete v; Это сообщение отредактировал(а) Step - 27.2.2003, 01:57 -------------------- - Дурак учится на своих ошибках, умный на чужих. - умные учатся у дураков |
||||
|
|||||
DENNN |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3878 Регистрация: 27.3.2002 Где: Москва Репутация: 1 Всего: 43 |
Почитай внимательно про область видимости и операторные скобки {....};
|
|||
|
||||
Step |
|
||||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5151 Регистрация: 26.9.2002 Где: дурдом.UA Репутация: 5 Всего: 25 |
правильно вот так
-------------------- - Дурак учится на своих ошибках, умный на чужих. - умные учатся у дураков |
||||
|
|||||
dAnIK SeNT |
|
|||
Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 8.2.2003 Где: Казань Репутация: нет Всего: нет |
А как же со строками? Почему прокатывает
char *v; v = "sdfsdfsdf"; И как в этом случае выделять/освобождать память? |
|||
|
||||
AntonSaburov |
|
|||
![]() Штурман ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 5658 Регистрация: 2.7.2002 Где: Санкт-Петербург Репутация: нет Всего: 118 |
Это точно такое же статическое размещение. Строка "sdfsdf" размещается в области глобальных данных, а myvar указывает на эту область. Так что в данном случае ничего освобождать не надо. |
|||
|
||||
Alex101 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 891 Регистрация: 8.4.2002 Где: Москва Репутация: нет Всего: 10 |
А так нельзя делать. Надо сначала память под var1 выделить. А тут у тебя не должно ничего выделяться, просто семь байтов, начиная с var1 будут заняты твоей строкой, при этом, если там находятся данные, то они будут потеряны (навсегда ![]() Это сообщение отредактировал(а) Alex101 - 27.2.2003, 03:59 -------------------- С уважением, А. Фролов. |
|||
|
||||
Kefir |
|
|||
«Hakuna Matata» ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1878 Регистрация: 25.1.2003 Где: Tampere, Suomi Репутация: нет Всего: 87 |
а не легче делать char *var = new char; тут ясно и понятно, что так, мол, и так, выделяю память под мой var. А потом просто delete var;
|
|||
|
||||
Fantasist |
|
||||
![]() Лентяй ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1517 Регистрация: 24.3.2002 Репутация: 4 Всего: 41 |
Можно. Антон уже сказал. Строковый литерал (типа "....") имеет тип, точно не скажу какой, но, можно считать, что char* и выделяется статически, скорее всего в сегменте данных, и лежит там всегда с начала запуска программы до ее уничтожения. Когда вы присваиваете указателю char* значение такого литерала, вы просто записываете в указатель значение памяти, где лежит эта строка. -------------------- Волны гасят ветер... |
||||
|
|||||
Fantasist |
|
|||
![]() Лентяй ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1517 Регистрация: 24.3.2002 Репутация: 4 Всего: 41 |
Легче разобраться, и никаких проблем. ![]() -------------------- Волны гасят ветер... |
|||
|
||||
Alex101 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 891 Регистрация: 8.4.2002 Где: Москва Репутация: нет Всего: 10 |
2Fantasist Точно, строка в сегменте данных лежит. Потом в указатель ее адрес помещается.
Сори всем за свои поспешные выводы. Но все равно, так делать, скажем, некрасиво, что ли.... (с точки зрения кода) -------------------- С уважением, А. Фролов. |
|||
|
||||
Vaulter |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1724 Регистрация: 30.12.2002 Где: бункер Репутация: 2 Всего: 22 |
так, будет выделено памяти только под один символ. |
|||
|
||||
dAnIK SeNT |
|
||||
Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 8.2.2003 Где: Казань Репутация: нет Всего: нет |
А так правильнее?
ЗЫ. Спасибо всем огромное за ответы ![]() |
||||
|
|||||
BlowFish |
|
||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 97 Регистрация: 29.3.2002 Где: Санкт-Петербург Репутация: нет Всего: нет |
2 Step: Это же плохой пример, т.к. выделив сначала память
2 Fantasist: строковый литерал имеет тип const char*... |
||||||
|
|||||||
Step |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5151 Регистрация: 26.9.2002 Где: дурдом.UA Репутация: 5 Всего: 25 |
прокатывает по тому что твоя строка это масив символов, имя масива это всегда указатель и по этому оно прокатывает, а вот имя масива и число в квадратных скобках это уже значение, а не указатель -------------------- - Дурак учится на своих ошибках, умный на чужих. - умные учатся у дураков |
|||
|
||||
Step |
|
||||||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5151 Регистрация: 26.9.2002 Где: дурдом.UA Репутация: 5 Всего: 25 |
ты конечно прав, но только в том случае если pyfxtybt *v на месте ..... не использовалось
ну а при переадресации желательно конечно сделать делет -------------------- - Дурак учится на своих ошибках, умный на чужих. - умные учатся у дураков |
||||||
|
|||||||
Fantasist |
|
||||
![]() Лентяй ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1517 Регистрация: 24.3.2002 Репутация: 4 Всего: 41 |
Если было бы так, я бы не смог присвоить его значение не константному указателю. То есть такое не компилировалось бы:
Скорее этот тип char const* Но на самом деле, он имеет тип char[] ![]() P.S. Для интересующихся: в VC++ посмотрите на сообщение компилятора, на такое выражение: ("dfdfsd")=(char*)(0x1); Это сообщение отредактировал(а) Fantasist - 28.2.2003, 01:44 -------------------- Волны гасят ветер... |
||||
|
|||||
AntonSaburov |
|
|||
![]() Штурман ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 5658 Регистрация: 2.7.2002 Где: Санкт-Петербург Репутация: нет Всего: 118 |
Мало того. Если написать что-то вроде такого char* var1 = "12345"; char* var2 = "12345"; то оптимизатор скорее всего оставит всего одну строку в сегменте данных, а обоим указателям присвоит один и тот же адрес. Для меня обычным стало правило, что такого рода указатели объявлять как константы и использовать именно в таком ракурсе. В этом случае никаких проблем не возникает. Хотя хорошо, что такой вопрос возник - значит думаем, смотрим, замечаем. Хорошая смена нам, старикам, растет ![]() |
|||
|
||||
Fantasist |
|
|||
![]() Лентяй ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1517 Регистрация: 24.3.2002 Репутация: 4 Всего: 41 |
Вряд ли. Это очень опасное предположение - нет никакой гарантии, что я не хочу изменить первую строку не изменяя второй. -------------------- Волны гасят ветер... |
|||
|
||||
Step |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5151 Регистрация: 26.9.2002 Где: дурдом.UA Репутация: 5 Всего: 25 |
ну, это смотря на кокую глубину оптимизатор смотреть будет -------------------- - Дурак учится на своих ошибках, умный на чужих. - умные учатся у дураков |
|||
|
||||
Fantasist |
|
|||
![]() Лентяй ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1517 Регистрация: 24.3.2002 Репутация: 4 Всего: 41 |
Разве что в простешем случае. Я могу сохранить этот адрес в переменной, и изменить в другом юните компиляции - оптимизатор туда заглянуть не может. -------------------- Волны гасят ветер... |
|||
|
||||
Step |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5151 Регистрация: 26.9.2002 Где: дурдом.UA Репутация: 5 Всего: 25 |
Fantasist а ты выставь максимальный уровень проверки, и посмотри предупреждения при компиляции
-------------------- - Дурак учится на своих ошибках, умный на чужих. - умные учатся у дураков |
|||
|
||||
BlowFish |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 97 Регистрация: 29.3.2002 Где: Санкт-Петербург Репутация: нет Всего: нет |
Смотрю СтраусТрупа
![]() В "С" строковый литерал имел тип char*, а в С++ - const char[]. Для совместимости кода С и С++ разрешается присваивание char* p = "abc"; Но вот изменение, например: p[0] = 'A' приведет к ошибке. На счет "оптимизатора"... В VC++6 результатом такого кода:
Что и требовалось доказать |
|||
|
||||
Step |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5151 Регистрация: 26.9.2002 Где: дурдом.UA Репутация: 5 Всего: 25 |
*(p+1)='d' - прокатит -------------------- - Дурак учится на своих ошибках, умный на чужих. - умные учатся у дураков |
|||
|
||||
dim |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 106 Регистрация: 24.12.2002 Репутация: нет Всего: нет |
В VisualC компилятор будет делать это только если включена опция /Gf или /GF, не знаю как Builder. --------------------
that's all |
||||
|
|||||
Fantasist |
|
|||
![]() Лентяй ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1517 Регистрация: 24.3.2002 Репутация: 4 Всего: 41 |
Значит VC расходиться здесь со стандартом. Если считать, что он должен быть const char[], то тогда можно и оптимизацию вышеописанную проводить. -------------------- Волны гасят ветер... |
|||
|
||||
BlowFish |
|
||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 97 Регистрация: 29.3.2002 Где: Санкт-Петербург Репутация: нет Всего: нет |
не прокатит (специально попробывал запустить прогу) |
||||
|
|||||
Step |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5151 Регистрация: 26.9.2002 Где: дурдом.UA Репутация: 5 Всего: 25 |
-------------------- - Дурак учится на своих ошибках, умный на чужих. - умные учатся у дураков |
|||
|
||||
Molnienosetz |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 107 Регистрация: 6.3.2003 Где: Россия, Королёв, комитетский лес Репутация: нет Всего: нет |
Хочу сделать замечание. Если необходимо удалить кусок памяти, выделенный так:
char *ptch = new char [1024]; , то вроде как надо писать delete [] ptch; Это обязательно? Причём насколько я знаю, в книжках (я прочитал с полтора десятка) ничего на эту тему нет, этот вопрос подробно освещён только в одной - как-то там про VC++. Там ещё пишут, что если квадратные скобки опустить, то высвободится память только из под первого объекта. Вопрос не по теме: я воще новичок, ничо, что я везде суюсь? --------------------
"Вы только появились на форуме, но уже стали весьма популярны. Правда не как профессионал, а большой зазнайка."Это про меня! :) (В том смысле, что писалось не про меня.) |
|||
|
||||
Step |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5151 Регистрация: 26.9.2002 Где: дурдом.UA Репутация: 5 Всего: 25 |
-------------------- - Дурак учится на своих ошибках, умный на чужих. - умные учатся у дураков |
|||
|
||||
Fantasist |
|
||||
![]() Лентяй ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1517 Регистрация: 24.3.2002 Репутация: 4 Всего: 41 |
Ничего себе! Как это нет? Что же это за книжки такие? Если используется new[] то для него необходимо использовать delete[].
Помниться, по этому вопросу (о необходимости delete[]) большое обсуждение было. Вообще, как пологается по стандарту, я уже сказал, а вот как реализуют это компиляторы - вопрос другой. Чаще всего, и именно для такой реализации стандарт таким образом и был придуман, когда выделяется память с помощью new - где-то (положим, на два байта выше выделенного блока) сохраняется размер выделенного куска. Если выделение памяти происходит с помощью new[] - то сохраняется и количество выделенных элементов. А зачем нам это количество? Ведь delete может просто взять сохраненный размер выделенного блока и грохнуть его. Для простых типов это действительно так, но для пользовательских нужно знать сколько раз вызвать деструктор. То есть так и получается, что для простых типоа достадочно было и одного delete , а delete[] в общем-то излишен, однако для сложных типов это не так. С другой стороны, можно было бы всегда сохранять количество выделенных элементов, в независимости от того, используется new или new[] , однако это не так экономно, с точки зрения расходуемой памяти. Зачем хранить количество элементов для new, когда и так понятно, что он один? Так и получается, что предпологается, что delete не смотрит на количество элементов (то есть просто считает, что он один), а delete[] смотрит. В большинстве реализаций, для простых типов, уничтожение с помощью delete будет оказывать тот же эффект, что и delete[] , так как сохраняется размер всего выделенного блока, а не размер элемента*количество элементов. Так что если применить delete, для памяти выделенной с помощью new[] , то память освободиться вся, но деструкор будет вызван только для первого элемента. -------------------- Волны гасят ветер... |
||||
|
|||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |