| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Заполнить выделенную динамическую память нулями |
| Автор: Alca 21.8.2008, 15:57 | ||||
| Заполнить выделенную динамическую память нулями ('\0')? например буфер можно обнулить так:
Можно ли делать так?
Заполниться ли выделенная память нулями? |
| Автор: cutwater 21.8.2008, 16:01 |
| Естественно можно |
| Автор: UnrealMan 21.8.2008, 17:26 | ||||
А можно и так:
В случае с new стандарт позволяет записывать так:
Но не все современные компиляторы соблюдают стандарт в этом плане (например, MinGW 3.4.5 тупо не инициализирует массив). |
| Автор: Alek86 21.8.2008, 17:41 |
| кстати, вопрос немного филогсофский обычно не рекомендуют смешивать сишный стиль и плюсовой кто из программистов тогда использует вместо memset std::uninitialized_fill? |
| Автор: Alek86 21.8.2008, 18:07 |
| лучше чем memset |
| Автор: UnrealMan 21.8.2008, 18:13 |
О-о-о, да, мы избавились от необходимости умножения на sizeof(тип элемента массива). Аллилуйя! Мегадостижение. А что мсье будет делать, если тип элементов массива сменится с POD на не POD? |
| Автор: andrew_121 21.8.2008, 18:32 | ||||
Просто немного не так:
|
| Автор: UnrealMan 21.8.2008, 18:44 | ||||
Я про второй свой пример говорил (с new который). Первый, к счастью, работает и в MinGW. Добавлено через 12 минут и 43 секунды Кстати, по стандарту, в отличие от
код
гарантированно инициализирует лишь первые два элемента символьного массива. |
| Автор: vinter 21.8.2008, 19:13 | ||
ну тогда исчезнет необходимость в обнулении, спор то как раз о POD типах |
| Автор: Alca 21.8.2008, 19:16 | ||
|
| Автор: UnrealMan 21.8.2008, 19:34 |
... и ради достижения корректности программы возникнет необходимость в устранении существующего обнуления, причём компилятор на эту необходимость не укажет. Коли уж наша программа разваливается, стоит нам на шаг отойти от POD-типов, о каком C++-стиле может идти речь? Я тут никакого спора не вижу. Если некое средство считается более крутым лишь потому, что оно из STL, а не из стандартной библиотеки C, то это не что иное, как детский сад. Над псевдоинтеллектуальными рассуждениями я обычно просто стебусь, а не спорю с ними. |
| Автор: bsa 21.8.2008, 20:53 | ||||
Этот код может вызвать ошибку Access Violation или Segmentation fault, в зависимости от ОС. Это типичная ошибка новичка - выход за границы массива. |
| Автор: Alek86 21.8.2008, 21:25 | ||||
| немного оффтоп если не заметил, у меня стоял знак вопроса а это значит, что я задавал вопрос и ожидал ответа а не ржачки (кстати нормального ответа, почему все так любят memset и ни разу не используют std::uninitialized_fill)
а поскольку ты над всеми стебешься, кто с тобой не согласен, то... и по теме
насколько я вижу в примерной реализации std::uninitialized_fill там вообще не идет речи ни о ПОД ни о каком-то конкретном куске памяти. есть только 2 итератора и значения. что ты имел в виду, когда писал о ПОД? (только, пожалуйста, если можно, ответь серьезно, без клоунады) |
| Автор: andrew_121 21.8.2008, 21:36 |
Респект и уважуха |
| Автор: bsa 21.8.2008, 21:43 |
| Подозреваю, что об uninitialized_fill мало кто знает, поэтому и не используют. Все-таки это низкоуровневая функция. С другой стороны, она может быть удобна в случае "нестандартного" для С++ выделения памяти (malloc) - не нужно городить огород с размещающими new. Но я бы остерегся от использования этих нестандартных методов без крайней необходимости. |
| Автор: cutwater 21.8.2008, 21:53 |
| По поводу uninitialized_fill, могу высказать свое имхо memset работать должен все таки быстрее |
| Автор: Alek86 21.8.2008, 22:08 |
думаю, так и есть - в дебаге в релизе с оптимизацией с указателями должно быть то же самое хотя - кто знает (пробовать лень |
| Автор: UnrealMan 21.8.2008, 22:33 |
| Создание массива из n объектов определённого типа и выделение n байт сырой памяти - это разные задачи, и у каждой будет своё наиболее подходящее (хотя бы с точки зрения самодокументируемости кода) решение. В первом случае подходящим решением будет использвание new-expression, std::vector или иного контейнера, если первые два не подходят. Во втором случае подходящим решением будет явный вызов operator new. В первом случае при использовании new-expression для заполнения массива n элементами подходящим средством будет std::fill_n. Во втором случае для размещения n объектов в сырой памяти подходящим средством будет std::uninitialized_fill_n. При следовании такому принципу (каждой задаче - соответствующий метод решения) по коду по крайней мере будет видно, какая задача решается. |
| Автор: MTWizard 21.8.2008, 23:36 |
| unitialized_fill - более общее решение, т.к. работает и для подов, и для не-подов. Тем более, для типа signed/unsigned char unitialized_fill (по крайней мере в STLPort) превращается в memset Значит, эффективность она тоже обеспечивает. |
| Автор: UnrealMan 22.8.2008, 00:25 | ||||
Изначальный пример выглядел так:
Если заменить здесь memset на std::uninitialized_fill, а после char заменить на не POD класс, то получишь двойное конструирование объекта в одной и той же области памяти. Затея смешивания относительно высокоуровневого new-expression с низкоуровневым конструированием объекта поверх памяти в качестве замены "смешиванию плюсового и сишного стиля" достойна похвал. |
| Автор: Alek86 22.8.2008, 11:20 | ||
тогда моя ошибка я говорил не об этом примере, а вообще стоило создать новую тему... в общем, насколько я понял, в тех случаях когда надо, программисты используют memset вместо std::uninitialized_fill в основном потому, что о таком не знают.
а в случае, если не менять memset на std::uninitialized_fill, а сразу менять чар на не ПОД класс? вроде тогда вообще ж... будет |
| Автор: cutwater 22.8.2008, 11:29 |
| Обычно таких проблем не возникает. Они решаются на стадии проектирования, и там где нужен char - он нужен. Если в последствии приходится менять тип и замена memset на uninitialized_fill окажется трудоемкой, то проект хренов по определению. Добавлено через 21 секунду Все вышесказанное опять же мое ИМХО |
| Автор: Alca 22.8.2008, 11:58 | ||
А если структура объявленатак:
Как ее обнулить? |
| Автор: W4FhLF 22.8.2008, 12:18 |
| Alca, смотря как ты её создаёшь. Выше было приведено как минимум два характерных способа. Попробуй. |
| Автор: Alek86 22.8.2008, 12:42 |
| Alca, старайся не смешивать С и С++ что значит "обнулить" структуру? привести к дефолтному состоянию? тогда тебе поможет доюбавление в структуру функции Reinit(), которая будет вызываться также и в конструкторе. и структура потихоньку начнет превращаться в класс |
| Автор: Alca 22.8.2008, 12:59 | ||
| Обнулить (сорри за такие термины) - значит инициализировать выделяемую память '\0'. Создаю так:
Надо через memset. |
| Автор: bsa 22.8.2008, 13:12 |
| PHOSTENT - Это что? макрос? Что он определяет? Это указатель или структура? POD или не POD? Язык программирования Си или С++? |
| Автор: Alca 22.8.2008, 13:23 | ||
Плюсы.
|
| Автор: mrbrooks 22.8.2008, 14:30 |
| Я вообще предпочтаю обнулять все через макрос ZeroMemory(); в винде. |
| Автор: Alca 22.8.2008, 14:51 |
| И как через ZeroMemory()? |
| Автор: UnrealMan 22.8.2008, 14:58 | ||
Обнулить поля POD-структуры можно не прибегая к библиотечным функциям:
|
| Автор: mrbrooks 22.8.2008, 15:03 | ||
| Alca, к примеру
Добавлено через 1 минуту и 36 секунд так же можно обнулить любую структуру |
| Автор: Alca 22.8.2008, 15:06 | ||
Надо заполнить структуру:
|
| Автор: mrbrooks 22.8.2008, 15:16 | ||
|
| Автор: Alca 22.8.2008, 15:22 | ||
|
| Автор: mrbrooks 22.8.2008, 15:23 |
| Alca, согласен но где это ты у меня видел? Добавлено через 1 минуту и 48 секунд есесно что указатель вернет 4 байта. |
| Автор: UnrealMan 22.8.2008, 15:25 | ||
Никогда не понимал тех, кто так делает в плюсовых проектах.
Какой вариант короче? |
| Автор: Alca 22.8.2008, 15:26 |
| Не досмотрел, сорри... А можно получить размер структуры через указатель? |
| Автор: mrbrooks 22.8.2008, 15:26 | ||
| но я то беру размер основной струтуры. Добавлено через 1 минуту и 27 секунд
наврятли, но 100% утверждать не буду Добавлено через 2 минуты и 43 секунды UnrealMan, в |
| Автор: UnrealMan 22.8.2008, 15:30 | ||
|
| Автор: mrbrooks 22.8.2008, 15:34 |
| UnrealMan, имхо но для этого нужно прикрутить boost! А это целая эпопея. По крайней мере у \me так было. |
| Автор: Alca 22.8.2008, 15:35 | ||||
Boost, конечно вещь классная, но тягать её за собой чёта нехо.... |
| Автор: Partizan 22.8.2008, 15:38 |
| Alca, вы объявили указатель, а память не выделили... |
| Автор: bsa 22.8.2008, 15:40 | ||||||
можно и проще:
|
| Автор: UnrealMan 22.8.2008, 15:41 | ||
Существует не так уж много объективных причин, чтобы его не прикручивать. Добавлено @ 15:46 Можно.
|
| Автор: mrbrooks 22.8.2008, 15:47 |
| UnrealMan, имхо ты прав. я и спорить не буду. boost это та вещь которую стоит осваивать. |
| Автор: Alca 22.8.2008, 15:48 | ||
Я память динамически кажись не выделяю...
Я не объявлял указатель, тока дефайнил. |
| Автор: mrbrooks 22.8.2008, 15:52 | ||
| Alca, любопытно если переменну pHost объявить глобально - варнинг проподает. Добавлено @ 15:54 либо как
|
| Автор: Alca 22.8.2008, 15:56 | ||||
Ворнинг улетел! |
| Автор: mrbrooks 22.8.2008, 16:01 |
| кстати если не ошибаюсь глобальные и статические переменные по умолчанию инициализируются нулем. |
| Автор: bsa 22.8.2008, 16:02 | ||
так оно и есть |
| Автор: Partizan 22.8.2008, 16:05 | ||||||
PHOSTENT pHost; - это чтоли дефайн? |
| Автор: Alca 22.8.2008, 16:06 | ||
| Ворнинг улетел! А прога слетела!!! У меня 2 потока юзают эту функцию... Дефайнил так:
|
| Автор: Lazin 22.8.2008, 16:15 |
пардон за офтопик, ИМХО рано тебе еще потоки использовать |
| Автор: Alca 22.8.2008, 16:17 | ||
Надо использовать! Заодно и научюсь. |
| Автор: bsa 22.8.2008, 17:55 | ||
|
| Автор: Lazin 22.8.2008, 19:29 | ||
и не забыть освободить ее когда нужно Добавлено через 22 секунды хотя глобальную иногда можно не освобождать... |