Clear array of strings
What is the easiest way to clear an array of strings?
7 Answers 7
Note that this won’t change the size of the array — nothing will do that. Instead, it will set each element to null.
If you need something which can actually change size, use a List<string> instead:
It depends on circumstance (like: what is in the array) but the best method usually is to create a new one. Dropping all references to the old one.
I think you can also get away with this for example: SearchTerm = new string[]<>;
You can try this.
-
The Overflow Blog
Related
Hot Network Questions
Subscribe to RSS
To subscribe to this RSS feed, copy and paste this URL into your RSS reader.
Site design / logo © 2023 Stack Exchange Inc; user contributions licensed under CC BY-SA . rev 2023.3.11.43304
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.
Почему в С++ массивы нужно удалять через delete[]
Заметка рассчитана на начинающих C++ программистов, которым стало интересно, почему везде твердят, что нужно использовать delete[] для массивов, но вместо внятного объяснения – просто прикрываются магическим «undefined behavior». Немного кода, несколько картинок и взгляд под капот компиляторов – всех заинтересованных прошу под кат.

Введение
Может быть, вы не замечали, или даже просто не обращали внимания, но, когда вы пишете код для освобождения памяти, занятой массивами, то вам не приходится писать количество элементов, которые нужно удалить. При этом всё замечательно работает.
Это что, магия? Отчасти – да. Причём разработчики различных компиляторов видят и реализуют её по-разному.

Существует два основных подхода к тому, как компиляторы запоминают количество элементов в массиве:
- Запись количества элементов перед самим массивом («Over-Allocation»)
- Хранение количества элементов в обособленном ассоциативном контейнере («Associative Array»)
Over-Allocation
Первый способ, как понятно из названия, реализуется простой записью количества элементов перед массивом. Обратите внимание, что в таком случае указатель, который вы получите после выполнения оператора new, будет указывать на первый элемент массива, а не на его фактическое начало.

Такой указатель ни в коем случае нельзя передавать обычному оператору delete. Скорее всего, он просто удалит первый элемент массива, а остальные оставит нетронутыми. Заметьте, я не просто так написал «скорее всего» – ведь никто не может гарантировать, что произойдёт на самом деле и как дальше будет вести себя ваша программа. Всё зависит от того, какие объекты находились в массиве и делали ли они что-то важное в своих деструкторах. То есть получаем классическое неопределённое поведение. Согласитесь, это не то, чего вы ожидаете при попытке удалить массив.
Чем же отличается оператор delete[]? А он как раз считывает количество элементов в массиве, вызывает деструктор для каждого объекта и уже после этого очищает память (вместе со скрытой переменной).
Если кому будет интересно, то примерно в такой псевдокод превращается конструкция delete[] p; при использовании этой стратегии:
Этим способом пользуются компиляторы MSVC, GCC и Clang. В этом можно убедиться, взглянув на код работы с памятью в соответствующих репозиториях (GCC и Clang) или воспользовавшись сервисом Compiler Explorer.

Как видно на изображении выше (верхняя часть – код, нижняя – ассемблерный вывод компилятора), я набросал простенький код, в котором объявлена структура и функция для создания массива этих самых структур.
Что же происходит с точки зрения ассемблера простым языком:
- cтрока N3: запись требуемого количества памяти (20 байт на 5 объектов + 8 байт на размер массива) в регистр;
- cтрока N4: вызов оператора new для выделения памяти;
- cтрока N5: запись количества элементов в начало выделенной памяти;
- cтрока N6: смещение указателя на начало массива на sizeof(size_t), полученный результат является возвращаемым значением.
К достоинствам этого способа можно отнести его лёгкость в реализации и скорость работы, ну а к недостаткам – то, что он не прощает ошибок с некорректным выбором оператора delete. В лучшем случае – сразу получите падение программы с ошибкой «Heap Corrupt», а в худшем – будете долго и мучительно искать причины странного поведения программы.
Associative Array
Второй способ подразумевает существование скрытого глобального контейнера, в котором хранятся указатели на массивы и сколько элементов они содержат. В таком случае перед массивами нет никаких скрытых данных, а вызов delete[] p; реализуется примерно вот так:
Что ж, выглядит не так «магически», как прошлый вариант. Есть ли ещё какие различия? Да.
Кроме уже упомянутого отсутствия скрытых данных перед массивом, мы получаем небольшое замедление работы из-за необходимости поиска данных в глобальном хранилище. Но компенсируем это тем, что программа может более снисходительно относиться к неверному выбору оператора delete.
Данный подход использовался в компиляторе Cfront. Останавливаться на его реализации мы не будем, но если кому интересно покопаться во внутренностях одного из первых C++ компиляторов, то сделать это можно на GitHub.
Мини-послесловие
Всё вышеописанное является внутренней кухней компиляторов, и полагаться на то или иное поведение не стоит. Особенно это касается случаев, когда планируется портирование программы на разные платформы. Благо что есть несколько вариантов как можно избежать данного класса ошибок:
- Использовать семейства функций std::make_*. Например: std::make_unique, std::make_shared.
- Использовать средства статического анализа для раннего выявления ошибок, например PVS-Studio.
Если же вас заинтересовала тема неопределённого поведения и особенностей работы компиляторов, то могу посоветовать ещё парочку дополнительных материалов:
Как очистить массив символов в C?

Программирование и разработка
Массивы символов используются для хранения нескольких символьных элементов в непрерывно выделенной памяти. В нескольких вопросах у нас есть необходимость очистить массив символов, но вы не можете очистить массив символов, установив для отдельных членов какое-то значение, указывающее, что они ничего не содержат. Итак, нам нужны какие-то другие методы для выполнения этой задачи. Давайте проверим несколько методов для выполнения этой задачи.
Методы очистки массива символов в C упомянуты ниже:
- Использование элемента NULL
- Использование strcpy для очистки строки
- Использование memset для очистки
- Очистка динамического массива символов с помощью бесплатного
1. Очистка строки в C с использованием (’/0′)
Элемент ’\0′ в строке или массиве символов используется для идентификации последнего элемента массива символов. Для пустого массива символов первым элементом является элемент ’\0′. Итак, мы можем использовать это свойство строки для очистки массива.
обнулить массив в C
Как наиболее правильно обнулить массив данных в C? Чтобы был обнулен не только первый элемент, но достоверно стерлись и все остальные.
Re: обнулить массив в C
char a[100]; memset (a, 0, sizeof(a));
Re: обнулить массив в C
и не забывай продвинутые виндовуз компиляторы
при оптимизации просто
пропускают оператор memset(a,0,sizeof(a));
что делает gcc Хз )
PS: опять все приходиться делать вручную (((
Re: обнулить массив в C
С какого это перепоя? Если действительно есть такой компилятор, то это его глюк, а не оптимизация. Такое ощущение, что ты спутал 2 вещи:
— Просто выкинуть нафиг вызов memset.
— Вместо вызова memset использовать встроенный код (rep stosd или типа того). Т.е. по сути — тот же memset, но без накладных расходов на push+call+ret+add.
Re: обнулить массив в C
А ещё есть bzero. (может оно эфективнее будет)
Re: обнулить массив в C

Re: обнулить массив в C
char a[100]=<0>; Работает классно! И не надо выдрючиваться.

Re: обнулить массив в C
char a[100]=<0>; Работает классно! И не надо выдрючиваться.
Re: обнулить массив в C
2 kkk.
Такое ощущение, что в этом случае обнулится только a[0].
И потом, это работает только один раз. После того, как ты чего-то записал в `a’, а затем решил его обнулить, `a=<0>;’ вообще не прокатит.
Re: обнулить массив в C
2nobody:
kkk прав, при инициализации массива, элементам "не хватившим " значений — инициализируются неявно \0. Для случая
char a[100] = < 0 >
a[0] — явно инициализируется 0-м
a[1]-a[99] — неявно инициализируются 0-м
ps: аналогичным образом можно инициализировать и структуры.
pss: все это есть в стандарте.
Re: Re: обнулить массив в C
>2nobody: >kkk прав, при инициализации массива, элементам "не хватившим " >значений — инициализируются неявно \0. Для случая >char a[100] = < 0 >>a[0] — явно инициализируется 0-м >a[1]-a[99] — неявно инициализируются 0-м
>ps: аналогичным образом можно инициализировать и структуры. >pss: все это есть в стандарте.
——————— все что выше вранье. и зависит от компилятора но не факт покажы где есть в стандарте. используй memset