Очистка структуры
Если нужно заполнить её нулями при создании тогда так:
RGB rgb = <>;
Это эквивалентно следующему:
RGB rgb = ;
Если нужно обнулить существующий объект структуры, тогда используем memset :
RGB rgb; memset(&rgb, 0, sizeof(RGB));
Если нужно обнулить массив структур, тоггда делаем так:
memset(img, 0, sizeof(img))
Отслеживать
ответ дан 4 мая 2015 в 4:35
23.8k 3 3 золотых знака 47 47 серебряных знаков 61 61 бронзовый знак
Я думаю, вместо последней строчки имеловь в виду вот это: memset(img, 0, sizeof(RGB) * 512 * 512) — или это: memset(img, 0, sizeof(img)) (первый способ работает в том числе с указателем на первый элемент, второй же — только с массивами).
4 мая 2015 в 5:46
@PavelMayorov, я просто описался с img . Спасибо — поправил.
4 мая 2015 в 5:53
Так как у нас C++, а не C, предлагаю нормальное ООПное решение, а не «сишный путь» с обнулениями памяти по указателю.
Всё, что нужно сделать — это добавить конструктор:
struct RGB < BYTE rgbtBlue; BYTE rgbtGreen; BYTE rgbtRed; RGB() : rgbtBlue(0), rgbtGreen(0), rgbtRed(0) < >>; RGB img[512*512];
Если вы пользуетесь современным компилятором, то можете записать проще:
struct RGB < BYTE rgbtBlue = 0; BYTE rgbtGreen = 0; BYTE rgbtRed = 0; >;
Ну а если вы хотите сэкономить на конструкторе, то просто запишите:
RGB img[512*512] = <>;
Если вам нужно обнулить имеющуюся структуру, то можете воспользоваться std::fill :
std::fill(std::begin(img), std::end(img), RGB()); // идеально std::fill(img, std::end(img), RGB()); // тоже сойдёт std::fill(img, img + _countof(img), RGB()); // старый VC++
memset — это наследие от C. В C++ можно использовать языковые средства, а не полагаться на низкоуровневые операции с указателями и байтами.
Кроме того, memset не обладает идеальной кросс-платформенностью (впрочем, вы вряд ли встретитесь с таким железом), вы можете столкнуться с «неожиданностями» при добавлении полей сложных типов и так далее.
[C] Освободить память занятую структурой.
man getgrgid
RETURN VALUE
.
The return value may point to a static area which is overwritten by a subsequent call to getgrent(), getgrgid(), or getgrnam().
Попробуй юзать getgrgid_r
anonymous
( 16.08.10 13:04:37 MSD )
А как у вас выглядит getgrgid? И да, разве не надо до free(gr) сделать free(gr->gr_name) и т.д.?
Eddy_Em ☆☆☆☆☆
( 16.08.10 13:04:45 MSD )

Ты ее не выделил
Boy_from_Jungle ★★★★
( 16.08.10 13:06:23 MSD )
Ответ на: комментарий от Boy_from_Jungle 16.08.10 13:06:23 MSD
anonymous
( 16.08.10 13:07:25 MSD )
Ответ на: комментарий от Eddy_Em 16.08.10 13:04:45 MSD
[C] Освободить память занятую структурой.
При попытке освобождать сначала поля структуры:
free(gr->gr_name);
free(gr->gr_passwd);
Та же история:
*** glibc detected *** ./gr: free(): invalid pointer: 0x0000000012d26016 ***
milton
( 16.08.10 13:10:42 MSD ) автор топика
Ответ на: [C] Освободить память занятую структурой. от milton 16.08.10 13:10:42 MSD
Посмотрел man. Согласен с самым первым ответом. Вы вообще уверены, что тому, что возвращает getgrgid можно делать free?
А список gr_mem вы как освобождать собираетесь?
Eddy_Em ☆☆☆☆☆
( 16.08.10 13:19:28 MSD )
Ответ на: [C] Освободить память занятую структурой. от milton 16.08.10 13:10:42 MSD
Re: [C] Освободить память занятую структурой.
Бл*дь, ты ман то уже почитай по этой функции, что тебе указатель на структуру возвращает. Я тебе в первом посте уже процитировал, что далеко не факт, что там память вообще динамически аллоцируется, чтобы потом её free подсовывать.
anonymous
( 16.08.10 13:19:55 MSD )

if( (gr=getgrgid(gid)) == NULL) perror("GetGrGid "); fprintf(stdout,"Name: %s\n",gr->gr_name); free(gr); return 0; >
а можно вопрос? данная ветка кода выполняется только в том случае если у Вас (gr == NULL), то есть структура не создана, вот нафига её удалять?
и да, на будущее по code style, free() освобождает память, но не чистит значение указателя и он указывает, после free(), туда же куда и указывал, так что, хоть free() и проверяет на то что значение указателя не NULL, при попытке почистить второй раз будете получать ошибку
free(gr); gr = NULL;
shty ★★★★★
( 16.08.10 13:24:12 MSD )
Ответ на: комментарий от shty 16.08.10 13:24:12 MSD
если у Вас (gr == NULL), то есть структура не создана, вот нафига её удалять?
Это он просто так код оформил красиво, под if там только perror стоит.
dmsh
( 16.08.10 13:31:07 MSD )
Ответ на: комментарий от shty 16.08.10 13:24:12 MSD

и да, судя по отсутствию специализированной функции для удаления данной структуры, её чистка вообще не предполагается, то есть это просто набор указателей на внутренние структуры данных
shty ★★★★★
( 16.08.10 13:31:53 MSD )
Ответ на: Re: [C] Освободить память занятую структурой. от anonymous 16.08.10 13:19:55 MSD
Re: [C] Освободить память занятую структурой.
>>Бл*дь, ты ман то уже почитай по этой функции, что тебе указатель на структуру возвращает.
Бл*дь, спасибо, открыл глаза!
milton
( 16.08.10 13:33:52 MSD ) автор топика
Ответ на: комментарий от dmsh 16.08.10 13:31:07 MSD

если у Вас (gr == NULL), то есть структура не создана, вот нафига её удалять?
Это он просто так код оформил красиво, под if там только perror стоит.
от же блджад! с набегу подумал что опечатка, вообще я за такое по чайнику бил, виртуально конечно
«Обнуление» структур и массивов
Ведь по логике инициализации в таком случае должен инициализироватся только первый элемент массива, структуры.
Вот и возникло подозрение, что эта некая примочка то ли винды, то ли компилятора.
Собственно вопрос — гарантирует ли такой способ инициализации обнуление памяти? И соответствует ли он стандартам?
А то по старинке memset или ZeroMemory виндовую для обнуления использую.
22 ответа
27 февраля 2008 года
4.8K / / 20.01.2000
Хотелось бы уточнить очередную мелочь. Соответствует ли стандарту обнуление структуры или массива при объявлении таким вот образом:
struct COOLSTRUCT
int a;
char b;
>;
Ведь по логике инициализации в таком случае должен инициализироватся только первый элемент массива, структуры.
Вот и возникло подозрение, что эта некая примочка то ли винды, то ли компилятора.
Собственно вопрос — гарантирует ли такой способ инициализации обнуление памяти? И соответствует ли он стандартам?
А то по старинке memset или ZeroMemory виндовую для обнуления использую.
А почему бы самому не взять стандарт и не почитать?
Ответ: соответствует.
27 февраля 2008 года
223 / / 03.04.2006
А почему бы самому не взять стандарт и не почитать?
А смысл этого раздела на форуме?;) Я вот к примеру 3 справочника по С/С++ перерыл перед тем как этот вопрос задать. Так что моя совесть чиста 😀
27 февраля 2008 года
2.9K / / 03.08.2007
Хотелось бы уточнить очередную мелочь. Соответствует ли стандарту обнуление структуры или массива при объявлении таким вот образом:
struct COOLSTRUCT
int a;
char b;
>;
Ведь по логике инициализации в таком случае должен инициализироватся только первый элемент массива, структуры.
Вот и возникло подозрение, что эта некая примочка то ли винды, то ли компилятора.
Собственно вопрос — гарантирует ли такой способ инициализации обнуление памяти? И соответствует ли он стандартам?
А то по старинке memset или ZeroMemory виндовую для обнуления использую.
COOLSTRUCT *test= NULL;
27 февраля 2008 года
2.7K / / 02.02.2008
А почему бы самому не взять стандарт и не почитать?
Ответ: соответствует.
К сожалению, нигде не встретил способа, как инициализировать массив из нескольких значений одним числом (типа int iArr[10]=;). И в учебниках не нашёл. Можете указать источник (и желательно страницу), в котором сказано об такой инициализации.
27 февраля 2008 года
223 / / 03.04.2006
[quote=oxotnik333]COOLSTRUCT *test= NULL;[/quote]
Вопрос был по инициализации статически создаваемой структуры.
[quote=Kogrom]К сожалению, нигде не встретил способа, как инициализировать массив из нескольких значений одним числом (типа int iArr[10]=;). И в учебниках не нашёл. [/quote]
Аналогичная ситуация. По идее, такая запись должна инициализировать только первый элемент массива. С какой стати должны обнулятся остальные, не понятно.
27 февраля 2008 года
4.8K / / 20.01.2000
К сожалению, нигде не встретил способа, как инициализировать массив из нескольких значений одним числом (типа int iArr[10]=;). И в учебниках не нашёл. Можете указать источник (и желательно страницу), в котором сказано об такой инициализации.
В первом посте ты говорил об обнулении, а теперь уже об «инициализации одним числом». Аппетит приходит во время еды? 🙂
Источник — стандарт C++.
7 If there are fewer initializers in the list than there are members in the aggregate, then each member not explicitly initialized shall be value-initialized (8.5).
[Example:
initializes ss.a with 1, ss.b with «asdf», and ss.c with the value of an expression of the form int(), that is, 0. ]
Исходя из этого, инициализировать дефолтовыми значениями можно даже так:
int iArr[10] = <>;
27 февраля 2008 года
2.7K / / 02.02.2008
В первом посте ты говорил об обнулении, а теперь уже об «инициализации одним числом». Аппетит приходит во время еды? 🙂
У меня не было такого поста. Автор того поста другой человек. Наверно пора заводить аватарку.
Источник — стандарт C++.
. and ss.c with the value of an expression of the form int(), that is, 0.
Исходя из этого, инициализировать дефолтовыми значениями можно даже так:
int iArr[10] = <>;
Тогда можно вобще не инициализаровать, все равно int по умолчанию будет нулём. И какой смысл в этой инициализации, если можно просто написать
int iArr[10];
27 февраля 2008 года
223 / / 03.04.2006
Да, это был я 🙂
Только не в курсе я, чем отличается обнуление при объявлении от инициализации.
Инициализировать то походу все же нужно, т.к. int нулем делает инициализация значением по умолчанию выражения int(), а не объявление.
struct noInit
int a;
char *b;
> tst;
Объявление всего лишь выделяет память нужного размера.
P.S. Пустой блок <> при инициализации не прокатывает :(.
27 февраля 2008 года
1.1K / / 01.08.2005
Да, это был я 🙂
Только не в курсе я, чем отличается обнуление при объявлении от инициализации.
И я не в курсе. Может тем что для инициализации надо знать чем инициализировать, а для обнуления даже 0 не нужен. XOR по памяти и все. Угадал ?
27 февраля 2008 года
7.3K / / 20.01.2000
И я не в курсе. Может тем что для инициализации надо знать чем инициализировать, а для обнуления даже 0 не нужен. XOR по памяти и все. Угадал ?
На сколько я знаю — есть термин «инициализация» — т.е. гарантированное присвоенное какого либо определенного значения какой либо вновь созданной переменной. «Обнуление» (если конечно такой термин существует 🙂 ) — это гарантированная установка переменной в 0.
28 февраля 2008 года
4.8K / / 20.01.2000
На сколько я знаю — есть термин «инициализация» — т.е. гарантированное присвоенное какого либо определенного значения какой либо вновь созданной переменной.
«Обнуление» (если конечно такой термин существует 🙂 ) — это гарантированная установка переменной в 0.
Такой термин применил кто-то из авторов вопроса.
На самом деле в этом контексте существует 3 термина:
zero-initialize,
default-initialize,
value-initialize
За подробностями следует обратиться к п.8.5 стандарта.
28 февраля 2008 года
2.7K / / 02.02.2008
Цитаты из стандарта
To zero-initialize an object of type T means:
…
if T is a scalar type (3.9), the object is set to the value 0 (zero), taken as an integral constant expression, converted to T;
…
if T is an array type, each element is zero-initialized;
Every object of static storage duration shall be zero-initialized at program startup before any other initialization takes place.
То есть, насколько я понял, если ничего не делать, то массив и проинициализируется нулём (zero-initialized). Значит, если просто записать
int iArr[10];
то, согласно стандарту, все элементы массива проинициализируются нулём. А колдовства с фигурными скобками в данном случае не требуется.
28 февраля 2008 года
4.8K / / 20.01.2000
Цитаты из стандарта
То есть, насколько я понял, если ничего не делать, то массив и проинициализируется нулём (zero-initialized). Значит, если просто записать
int iArr[10];
то, согласно стандарту, все элементы массива проинициализируются нулём. А колдовства с фигурными скобками в данном случае не требуется.
А где ты видишь в записи
int iArr[10];
инициализацию?
Инициализация описывается соотв. синтаксисом, см. п.п. 8.5.1 и 8.5.2
28 февраля 2008 года
2.7K / / 02.02.2008
Явно её нет, но меня смущает, то, что в стандарте я не нашел утверждения типа: если требуется произвести инициализацию нулем, следует записать выражение
тип имя_переменной[размер] = <>;
Кроме того, меня смущает выражение:
Every object of static storage duration shall be zero-initialized at program startup before any other initialization takes place.
которое я понимаю так, что всякая переменная должна быть инициализирована нулем, до того, как будет иметь место любая другая инициализация. Но насколько я понимаю, массив нельзя инициализировать дважды, значит, происходит скрытая инициализация при объявлении.
Может это спорный вывод, но подтверждение ему я нашел только в примере
float y[4][3] = <
< 1 >, < 2 >, < 3 >, < 4 >
>;
initializes the first column of y (regarded as a two-dimensional array)
and leaves the rest zero.
Комментарий к примеру я понимаю примерно так: инициализируется первый столбец, все остальные элементы остаются в нуле. Заметьте, ОСТАЮТСЯ, а не устанавливаются в ноль. Хотя, может я неправильно перевожу.
28 февраля 2008 года
4.8K / / 20.01.2000
Так тут вся тонкость в тех словах, которые ты почему-то упустил:
«Every object of static storage duration . «
Читаем пункт 3.7.1 стандарта, и удивляемся коду:
int main()
static int staticArray[20];
int localArray[20];
29 февраля 2008 года
1.1K / / 16.08.2003
int main()
static int staticArray[20];
int localArray[20] = <>;
int iVar;
int iVar2();
Так в чем же разница? Почему в языке сделано именно так? И почему статические объекты изначально забиты нулями? Постигнув принцип, уже не запутаешься.
29 февраля 2008 года
4.8K / / 20.01.2000
int main()
static int staticArray[20];
int localArray[20] = <>;
Хм. это было адресовано мне?
int iVar;
int iVar2();
Так в чем же разница? Почему в языке сделано именно так? И почему статические объекты изначально забиты нулями? Постигнув принцип, уже не запутаешься.
А при чем тут статические объекты?
int iVar; — определение переменной
int iVar2(); — объявление функции
29 февраля 2008 года
1.1K / / 16.08.2003
Хм. это было адресовано мне?
А при чем тут статические объекты?
int iVar; — определение переменной
int iVar2(); — объявление функции
Адресовано не вам.
int iVar;
int iVar2();
это обе пременные типа int, с небольшим отличием, связанным с темой топика
29 февраля 2008 года
4.8K / / 20.01.2000
int iVar;
int iVar2();
это обе пременные типа int, с небольшим отличием, связанным с темой топика
Ошибаешься. 🙂
Читаем «всем известную литературу».
29 февраля 2008 года
1.1K / / 16.08.2003
Ошибаюсь, а может здесь не хватает контекста.
29 февраля 2008 года
4.8K / / 20.01.2000
Ошибаюсь, а может здесь не хватает контекста.
Неа, просто ошибаешься, контекст здесь не при чем.
Смотрим «всем известную литературу»:
[quote=Бьярн Страустрап. Справочное руководство по C++]
8.6 Инициализация
Заметьте, что поскольку () не является инициализатором, то «X a();» является не описанием объекта класса X, а описанием функции, не получающей значений и возвращающей X.
[/quote]
[quote=INTERNATIONAL STANDARD ISO/IEC 14882 Second edition 2003-10-15]
8.5 Initializers
8 [Note: since () is not permitted by the syntax for initializer,
is not the declaration of an object of class X, but the declaration of a function taking no argument and returning an X. The form () is permitted in certain other initialization contexts (5.3.4, 5.2.3, 12.6.2). ]
[/quote]
Наверное, ты имел в виду вот это:
Как очистить структуру c
lsv>Как ее быстро очистить (обнулить)?
Re: Очистка структуры
| От: | maximka_z |
| Дата: | 13.01.04 06:43 |
| Оценка: |
Здравствуйте, lsv, Вы писали:
lsv>Есть структура, например:
lsv>
struct Employ < lsv>int Id; lsv> char Name[10]; lsv> . lsv>> hd;
lsv>Как ее быстро очистить (обнулить)?
Employ e; memset(e, 0, sizeof(Employ));
Re[2]: Очистка структуры
| От: | Brick_1 |
| Дата: | 13.01.04 07:01 |
| Оценка: |
Здравствуйте, maximka_z, Вы писали:
_>Здравствуйте, lsv, Вы писали:
lsv>>Есть структура, например:
lsv>>
struct Employ < lsv>> int Id; lsv>> char Name[10]; lsv>> . lsv>>> hd;
lsv>>Как ее быстро очистить (обнулить)?
_>
_>Employ e; _>memset(e, 0, sizeof(Employ)); _>
Re: Очистка структуры
| От: | Lorenzo_LAMAS |
| Дата: | 13.01.04 07:15 |
| Оценка: |
YourStruct obj = <>; //не все компиляторы скомпилят, тогда: YourStruct obj = ; //ну или совсем по-дурацки YourStruct obj = YourStruct();
Of course, the code must be complete enough to compile and link.
Re[2]: Очистка структуры
| От: | Vamp |
| Дата: | 13.01.04 07:37 |
| Оценка: |
. YourStruct obj = YourStruct(); L_L>
В предположении, что конструктор структуры не инициализирует ее членов чем-либо другим.
Да здравствует мыло душистое и веревка пушистая.
Re: Очистка структуры
| От: | konst |
| Дата: | 13.01.04 07:38 |
| Оценка: |
Здравствуйте, lsv, Вы писали:
lsv>Есть структура, например:
lsv>
struct Employ < lsv>int Id; lsv> char Name[10]; lsv> . lsv>> hd;
lsv>Как ее быстро очистить (обнулить)?
тянет просто добавить свою ложку.
ну, про мемсет написали 10 раз уже
если она большая, а «нулить» надо часто.
struct Employ < int Id; char Name[10]; . bool isempty() const < return 0; > void clear() < >>
Re[3]: Очистка структуры
| От: | Lorenzo_LAMAS |
| Дата: | 13.01.04 07:39 |
| Оценка: |
V>В предположении, что конструктор структуры не инициализирует ее членов чем-либо другим.
Я вообще написал в предположении что очистка нужна в момент инициализации и мы имеем дело с агрегатом.
Of course, the code must be complete enough to compile and link.
Re[2]: Очистка структуры
| От: | Евгений Коробко |
| Дата: | 13.01.04 08:00 |
| Оценка: |
Согласен, что memset в С++ применять не стоит. Завтра вместо char Name[10] напишешь std::string Name, и будет задница. Я уж не говорю про вещественные поля, для которых такое обнуление может быть некорректным. Поэтому лучше всё-таки писать функцию обнуления. Да она и работать быстрее будет.
Posted via RSDN NNTP Server 1.8 beta
Евгений Коробко
Re[3]: Очистка структуры
| От: | Кодт | |
| Дата: | 13.01.04 13:03 | |
| Оценка: | 6 (1) | |
Здравствуйте, Евгений Коробко, Вы писали:
ЕК>Согласен, что memset в С++ применять не стоит. Завтра вместо char Name[10] напишешь std::string Name, и будет задница. Я уж не говорю про вещественные поля, для которых такое обнуление может быть некорректным. Поэтому лучше всё-таки писать функцию обнуления. Да она и работать быстрее будет.
Можно сделать зачистку места.
templateclass Final> struct zeroinit < // оставлено публичным на тот случай, если Final - POD-структура void init() < memset(static_cast(this), 0, sizeof(Final)); > // два стандартных конструктора - дефолтный и копирования zeroinit() < init(); >zeroinit(const zeroinit&) < init(); >>; struct Something : zeroinit < char buf[100]; int num; >;
Есть ограничения: не допускается, чтобы Something множественно наследовал от чего-то еще.
А в остальном всё зашибись.
Перекуём баги на фичи!
Re: Очистка структуры
| От: | Шахтер |
| Дата: | 13.01.04 20:00 |
| Оценка: |
Здравствуйте, lsv, Вы писали:
lsv>Есть структура, например:
lsv>
struct Employ < lsv>int Id; lsv> char Name[10]; lsv> . lsv>> hd;
lsv>Как ее быстро очистить (обнулить)?
Зависит от структуры. Вообще, в любой нормальной системе можно применять memset. Это не по стандарту, но достаточно быстро и в конкретных реализациях правильно. Но тут есть одна заковыка.
Ну например.
struct Example < int x; int y; >; Example object;
Вот здесь, скорее всего, наиболее быстрый способ — object.x=object.y=0; . Однако и способ с memset ом может быть столь же быстр и, более того, породить тот же самый код. Всё зависит от крутизны оптимизатора. Точно сказать нельзя. Необходимо эксперементировать с конкретным компилятором.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[4]: Очистка структуры
| От: | Евгений Коробко |
| Дата: | 14.01.04 05:39 |
| Оценка: |
Если честно, проверять лениво, но строка
struct Something : zeroinit
Вызывает серьёзные подозрения.
memset(static_cast(this), 0, sizeof(Final));
Зачем здесь преобразование типов?
И, главное, суть-то в том, что заполнять нулями некорректно в принципе:
struct MyStruct
std::string m_MyString;
>;
После этого структура находится в некорректном состоянии.
Posted via RSDN NNTP Server 1.8 beta
Евгений Коробко
Re[5]: Очистка структуры
| От: | Lorenzo_LAMAS |
| Дата: | 14.01.04 07:15 |
| Оценка: |
Здравствуйте, Евгений Коробко, Вы писали:
ЕК>Если честно, проверять лениво, но строка
ЕК>struct Something : zeroinit
ЕК>Вызывает серьёзные подозрения.
Это вообще-то не должно вызывать особых подозрений, особенно в наше время, когда полно всяких книг и статей и т.д. в которых такое сплошь и рядом.
ЕК>memset(static_cast(this), 0, sizeof(Final));
ЕК>Зачем здесь преобразование типов?
Я так думаю, что это на случай, если вдруг базовый подобъект будет идти после данных производного класса (Кодт, если я неправ, поясни, пожалуйста)
ЕК>И, главное, суть-то в том, что заполнять нулями некорректно в принципе:
ЕК>struct MyStruct
ЕК> <
ЕК> std::string m_MyString;
ЕК>>;
Это ты не по адресу, в исходном вопросе были члены встроенных типов. Кроме того, конструктор базы выполнится перед конструктором члена.