Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > инициализация памяти при выделении


Автор: ksili 27.12.2005, 12:07
В Си есть функция calloc(), которая при динамическом выделении памяти инициализирует всё нулями. Есть ли такая же возможность при выделении памяти оператором new?

Автор: adonin 27.12.2005, 12:11
Можно использовать функцию memset(). После выделения памяти заполните этот буфер нулями с помощью данной функции.

Автор: Neitron 27.12.2005, 12:12
Конкретно что тебе нужно инициализировать нулями? Класс?
Тогда memset

Автор: adonin 27.12.2005, 12:16
Свойства класса можно инициализировать в конструкторе класса, не прибегая к memset(). Если нужно инициализировать буфер - вот тогда memset().

Автор: MAKCim 27.12.2005, 22:00
опытным путем проверено, что
Код

T* array=new T [size];

обнуляет все size элементов T, если T примитивный встроенный тип

Автор: DeadSoul 27.12.2005, 22:10
Цитата(MAKCim @ 27.12.2005, 22:00)
опытным путем проверено, что
код C++
1:
T* array=new T [size];
обнуляет все size элементов T, если T примитивный встроенный тип

Компилятор\конфигурация? Подозреваю, что такое может быть только в Debug

Автор: ksili 28.12.2005, 05:22
Спасибо за советы, с memset работает гораздо быстрее.
Инициализировал массив. Интересно, а если надо инициализировать массив структур и обнулить надо не все поля, как проще? Наверно, переквалифицировать в класс и прописать необходимую инициализацию в конструкторе?

Автор: MAKCim 28.12.2005, 12:16
Цитата

Компилятор\конфигурация? Подозреваю, что такое может быть только в Debug


g++ 4.02 под Linux, конфигурация стандартная

Автор: Neitron 28.12.2005, 14:13
Цитата(MAKCim @ 28.12.2005, 12:16)
Цитата

Компилятор\конфигурация? Подозреваю, что такое может быть только в Debug


g++ 4.02 под Linux, конфигурация стандартная

Это не стандарт. Так что пофигу что оно так в твоем компиляторе.

Автор: byNet 28.12.2005, 15:54
Да

Автор: srd 28.12.2005, 16:48
Цитата(Neitron @ 27.12.2005, 19:12)
Конкретно что тебе нужно инициализировать нулями? Класс?
Тогда memset

Инициализировать объекта класса с помощью memset - это опасно.

Цитата(MAKCim @ 28.12.2005, 05:00)
опытным путем проверено, что
Код

T* array=new T [size];    

обнуляет все size элементов T, если T примитивный встроенный тип

Если я правильно понимаю п. 5.3.4/15 в стандарте, то для
Код

// T - примитивный тип
T* array = new T[size];

элементы массива имеют неопределенное значение, а для
Код

// T - примитивный тип
T* array = new T[size]();

элементы массива инициализируются нулём.



Автор: blackofe 28.12.2005, 20:29
Цитата(srd @ 28.12.2005, 16:48)
Инициализировать объекта класса с помощью memset - это опасно.

если учитывать, что класс от структуры ничем кроме видимости членов по-умолчанию не отличается, то инициализировать объекты класса не более опасно, чем объекты структур. имхо, надо смотреть в каждом конкретном случае.

как по мне, я вообще не люблю инициализацию объектов memset'ом. использую только для массивов, и то редко.

Цитата(srd @ 28.12.2005, 16:48)
Если я правильно понимаю п. 5.3.4/15 в стандарте, то для
Код

// T - примитивный тип
T* array = new T[size];

элементы массива имеют неопределенное значение, а для
Код

// T - примитивный тип
T* array = new T[size]();

элементы массива инициализируются нулём.

за это огромное спасибо. страшно полезно вот так открывать для себя что-то новое.

теперь мне memset и для массивов не нужен ;).

Автор: srd 29.12.2005, 06:38
Цитата(blackofe @ 29.12.2005, 03:29)
если учитывать, что класс от структуры ничем кроме видимости членов по-умолчанию не отличается, то инициализировать объекты класса не более опасно, чем объекты структур. имхо, надо смотреть в каждом конкретном случае.

С помощью ключевого слова struct можно определить POD-структуру, а можно определить класс. Здесь я говорил про классы вообще, а не про те, что вводятся с помощью ключевого слова class.

Цитата(blackofe @ 29.12.2005, 03:29)
за это огромное спасибо. страшно полезно вот так открывать для себя что-то новое.

теперь мне memset и для массивов не нужен ;).

Стандарт - вещь хорошая, но здесь надо смотреть на поведение конкретного компилятора smile memset'ом как-то надёжнее.

Автор: blackofe 29.12.2005, 22:07
базара для.

Цитата(srd @ 29.12.2005, 06:38)
С помощью ключевого слова struct можно определить POD-структуру, а можно определить класс. Здесь я говорил про классы вообще, а не про те, что вводятся с помощью ключевого слова class.

терминология. терминология. терминология.

как я понял, ты под словом "класс" подразумевал non-POD class? потому что POD-class - вполне себе нормальный термин. а поскольку с помощью ключевого слова struct можно определить и POD-структуру и non-POD-структуру, то я бы все-таки говорил о том, что есть

non-POD-структуры
non-POD-классы
POD-структуры
POD-классы

потому что класс, который класс, а не класс, тоже звучит как-то неубедительно. в конце концов, что такое класс? в стандарте есть такая фраза: "A class is a type." ну, так структура - тоже type. и int - тоже type.

гради буч дает такое определение: "класс - это некое множество объектов, имеющих общую структуру и общее поведение." ну, в общем-то, любой тип сюда подходит - и фундаментальный, и сложный. кстати, в стандарте среди сложных (compound) типов нет структур, как я понимаю они подразумеваются под ключевым словом class.

Цитата(srd @ 29.12.2005, 06:38)
Стандарт - вещь хорошая, но здесь надо смотреть на поведение конкретного компилятора smile memset'ом как-то надёжнее.

можно сказать, что любой компилятор реализует стандарт в той или иной степени. и если он не реализует стандартное поведение new(), то это можно расценивать как ошибку. с другой стороны реализация memset также не застрахована от ошибок. так что тут дело вкуса. лично я предпочитаю new и delete всяким malloc и free. красивее, изящнее, и как результат - читабельнее, а значит, более застраховано от ошибок кодирования.

Автор: LPBOY 30.12.2005, 23:28
Цитата(blackofe @ 28.12.2005, 20:29)
если учитывать, что класс от структуры ничем кроме видимости членов по-умолчанию не отличается, то инициализировать объекты класса не более опасно, чем объекты структур. имхо, надо смотреть в каждом конкретном случае.

Вообще-то кроме видимости членов по умолчанию, структуры от классов отличаются еще видимостью баз по умолчанию.

ИМХО memset для объекта класса(или структуры) действительно опасно.
Самая явная проблема - у класса могут быть виртуальные функции и/или виртуальные базы, с помощью memset'a мы испортим всю служебную информацию, хранящуюся в таком классе.

Кроме того если в классе есть данные-члены указатели или вещественного типа, то обнулив этот класс memset'ом мы можем получить не то, что ожидали. Данные-члены вещественного типа не обязательно будут равны 0.0 (для IEEE754 это так, но это не единственный возможный формат),
и для указателей тоже не гарантируется, что обнулив все биты мы получим указатель значение которого "null pointer value".

Автор: malor 9.7.2011, 19:42
Если создавать структуру так:
TMyStruct* pMyStruct = new TMyStruct();
то в полях pMyStruct ->FieldN будет лежать то, что положено в них конструктором структуры. 

Если сделать так:
TMyStruct  *pMyStruct  = (TMyStruct *)malloc(sizeof(TMyStruct ));
то в полях структуры будут лежать случайные данные, и придется увеличивать код на еще одну строку, а именно:
*pMyStruct  = (Value1, Value2, Value3, Value4);

Как-то можно избежать этого дополнительного шага ?

VS2008 

Автор: volatile 10.7.2011, 00:57
malor, тема то не вчера обсуждалась... 
Вообще-то new для того и придумали чтоб он конструктор вызывал.

Но если уж так приспичило выделять память именно с помощью malloc, то можно и так.
Но затем нужно вызвать размещающий нью.

Пример кода приводить не буду, а то снова какой-нибудь сумасшедший, типа сыроежки наброситься, неделю отбиваться буду. smile 

поищите по ключевым словам:
placement new
placement delete


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)