Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.82/119: Рейтинг темы: голосов - 119, средняя оценка - 4.82
Почетный модератор
Эксперт С++
5850 / 2861 / 392
Регистрация: 01.11.2011
Сообщений: 6,907
1

Создание динамического массива структур и его удаление

06.02.2013, 10:06. Показов 24390. Ответов 36

Author24 — интернет-сервис помощи студентам
Господа, поясните пожалуйста следующий момент:
создаю структуру:
C++
1
2
3
4
5
6
7
struct TTagList
  {    
  WideString Comment;            
  int State;             
  bool Visible;         
  };
TTagList *TTList;
далее в функции:
C++
1
2
int SomeCount = 15;
TTList = new TTagList[SomeCount];
обращаюсь к элементам "динамической структуры" (вдруг кому пригодится):
C++
1
2
3
4
5
TTList[0].Visible = true;
TTList[0].State = 1;
TTList[0].Comment = L"Комментарий";
TTList[1].Visible = false;
...
удаляю следующим образом:
C++
1
delete [] TTList;
Вопрос: как delete узнает сколько чего удалять, когда как sizeof дальше четырехбайтного указателя ничего не видит?
P.S. И правильно ли удалять такую конструкцию именно delete [], а не просто delete?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.02.2013, 10:06
Ответы с готовыми решениями:

Удаление динамического массива структур
Если удалять массив структур как обычно пишут, то при запросе следующей структуры из массива на...

Создание копии динамического массива структур
Есть динамический массив структур, есть сортировка. Проблема заключается в том, что если сделать...

Создание динамического массива структур
Нужно создать структуру с тремя переменными char int int С динамическим увеличением памяти...

Преобразование кода в ряд структур, создание динамического массива
Здравствуйте, у меня вопрос, как данный ниже код можно преобразовать в структурах, чтобы массив был...

36
Почетный модератор
Эксперт С++
5850 / 2861 / 392
Регистрация: 01.11.2011
Сообщений: 6,907
08.02.2013, 11:01  [ТС] 21
Author24 — интернет-сервис помощи студентам
mimicria, спасибо, что еще раз мне напомнили о занулении указателей.
Цитата Сообщение от mimicria Посмотреть сообщение
Нет, не равнозначны. Когда уже престанете страдать ерундой и начнёте читать по теме?
Хорошо. По теме.
SatanaXIII >> delete так же ничего не удаляет, а просто заставляет считать, что память под указателем свободна?
Avazart >> А что это как не удаление ?
SatanaXIII >> А вот это я получается удаляю массив? То есть две следующие записи равнозначны?
Ваша фраза о том, что
Цитата Сообщение от mimicria Посмотреть сообщение
операция delete в C++ безопасна для нулевого указателя.
говорит лишь о том, что те две записи не равнозначны и сначала нужно занулить указатель, а потом уже удалять его сколько душе угодно. Это все бесспорно так и есть. Но вот, как мне показалось, Avazart считает, что равнозначны.
Перфразирую:
SatanaXIII >> delete больше ничего не делает как только освобождает память под указателем на массив?
Avazart >> Это и есть удаление массива.
SatanaXIII >> Удаление указателя на массив это и есть удаление массива?
mimicria >> Нет.
Возвращаясь к теме, если delete что-то делает помимо освобождения указателя, то что?

Как именно он освобождает память? И в чем отличие от простого зануления указателя?
0
return (true);
1976 / 1111 / 221
Регистрация: 19.04.2011
Сообщений: 2,345
08.02.2013, 11:20 22
Цитата Сообщение от SatanaXIII Посмотреть сообщение
и сначала нужно занулить указатель, а потом уже удалять его сколько душе угодно
Ваши фразы говорят о том, что вы совсем не понимаете сути выделения и освобождения памяти. new выделила память и вернула действующий указатель. Эта область памяти в куче помечается как занятая. delete по указателю пометил выделенную память как освобождённую. Обнуление указателя делается на случай повторного вызова delete ПОСЛЕ освобождения памяти. Если вы уверены, что указатель точно больше нигде случайно не будет использован, то обнуление указателя можно и не делать.

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

Добавлено через 4 минуты
Цитата Сообщение от SatanaXIII Посмотреть сообщение
если delete что-то делает помимо освобождения указателя, то что?
Почитайте уже
В языке программирования C++ оператор delete возвращает память, выделенную оператором new, обратно в кучу. Вызов delete должен происходить для каждого вызова new, чтобы избежать утечки памяти. После вызова delete объект, указывающий на этот участок памяти, становится некорректным и не должен больше использоваться. Многие программисты присваивают 0 (нуль-указатель) указателям после использования delete, чтобы минимизировать количество ошибок программирования.
0
Почетный модератор
Эксперт С++
5850 / 2861 / 392
Регистрация: 01.11.2011
Сообщений: 6,907
08.02.2013, 11:32  [ТС] 23
Цитата Сообщение от mimicria Посмотреть сообщение
Ваши фразы говорят о том, что вы совсем не понимаете сути выделения и освобождения памяти.
По этому я и спрашиваю. ) Да, да, да, пойду книжки читать.

Цитата Сообщение от mimicria Посмотреть сообщение
new выделила память и вернула действующий указатель. Эта область памяти в куче помечается как занятая. delete по указателю пометил выделенную память как освобождённую. Обнуление указателя делается на случай повторного вызова delete ПОСЛЕ освобождения памяти.
Вот теперь понятно. Спасибо. Еще бы для полного понимания знать механизм вот этого, в трех словах:
Цитата Сообщение от mimicria Посмотреть сообщение
delete по указателю пометил выделенную память как освобождённую
Но вертаясь к первоначальному вопросу: получается никак нельзя по указателю узнать размер массива? И сам delete так же не знает этого, правильно?
0
return (true);
1976 / 1111 / 221
Регистрация: 19.04.2011
Сообщений: 2,345
08.02.2013, 11:45 24
Цитата Сообщение от SatanaXIII Посмотреть сообщение
получается никак нельзя по указателю узнать размер массива?
Для частных случаев решение возможно, общего решения нет. Да оно и не нужно никому.
Цитата Сообщение от SatanaXIII Посмотреть сообщение
И сам delete так же не знает этого, правильно?
delete вообще ничего не знает, это же функция
Записать, а потом найти количество элементов для вызова деструкторов - задача компилятора.
0
Почетный модератор
Эксперт С++
5850 / 2861 / 392
Регистрация: 01.11.2011
Сообщений: 6,907
08.02.2013, 11:59  [ТС] 25
Цитата Сообщение от mimicria Посмотреть сообщение
Для частных случаев решение возможно, общего решения нет. Да оно и не нужно никому.
Удобнее было бы на мой взгляд. К примеру глобально объявленный массив инициируется в какой-то функции. Зачем мне объявлять глобально инициализирующую переменную и везде ее таскать за собой, когда можно было бы померить массив, когда это потребовалось.

А вон тот мой фокус с вычислением количества элементов целочисленного массива почему сработал?
0
return (true);
1976 / 1111 / 221
Регистрация: 19.04.2011
Сообщений: 2,345
08.02.2013, 12:16 26
Цитата Сообщение от SatanaXIII Посмотреть сообщение
К примеру глобально объявленный массив инициируется в какой-то функции. Зачем мне объявлять глобально инициализирующую переменную и везде ее таскать за собой
Потому что в большинстве хороших программ глобально объявленные массивы, переменные и прочее на самом деле используются крайне редко. Когда вы это поймёте, большинство вопросов отпадут сами собой.
Цитата Сообщение от SatanaXIII Посмотреть сообщение
А вон тот мой фокус с вычислением количества элементов целочисленного массива почему сработал?
Возможно, это тот самый частный случай для отдельно взятого компилятора. Возможно, это совпадение. Вы ведь не все возможные варианты проверили? Например, для массивов структур? Так что пока это не более, чем фокус.
0
Почетный модератор
Эксперт С++
5850 / 2861 / 392
Регистрация: 01.11.2011
Сообщений: 6,907
08.02.2013, 12:21  [ТС] 27
Цитата Сообщение от mimicria Посмотреть сообщение
Потому что в большинстве хороших программ глобально объявленные массивы, переменные и прочее на самом деле используются крайне редко. Когда вы это поймёте, большинство вопросов отпадут сами собой.
Понял.

Цитата Сообщение от mimicria Посмотреть сообщение
Возможно, это тот самый частный случай для отдельно взятого компилятора. Возможно, это совпадение. Вы ведь не все возможные варианты проверили? Например, для массивов структур? Так что пока это не более, чем фокус.
Если вас не затруднит, попробуйте провернуть тоже самое у себя. Получится?
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
08.02.2013, 12:41 28
C++
1
2
delete mas;
mas = NULL;
Во первых массив удаляют delete[] а не просто delete.
Во вторых после удаления mas продолжает указывать туда где раньше были данные, которых теперь нет
( то есть они могут и дальше там лежать а могут и нет т.е. - мусор )

Добавлено через 3 минуты
Цитата Сообщение от SatanaXIII Посмотреть сообщение
А вон тот мой фокус с вычислением количества элементов целочисленного массива почему сработал?
Работал по тому что то массив, а не указатель на массив
0
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
08.02.2013, 13:07 29
SatanaXIII, соглашусь с вами, что было бы не плохо получать размер массива по указателю на него. Но нет такой ф-ции! Нет и все тут. Вы можете придумать разные фокусы, что бы обойти это, но это только фокусы, сегодня они работают, а завтра нет. Смиритесь с тем, что вам придется таскать с собой размер массива или использовать другие возможности языка (списки, вектора и т.д.).
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
08.02.2013, 13:09 30
Цитата Сообщение от gumi250 Посмотреть сообщение
SatanaXIII, соглашусь с вами, что было бы не плохо получать размер массива по указателю на него.
ЗачеМо оно надоВо ?
Если для этого есть контейнеры, а массивы это больше наследие Си
0
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
08.02.2013, 13:17 31
массивы быстрее
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
08.02.2013, 13:19 32
Цитата Сообщение от gumi250 Посмотреть сообщение
массивы быстрее
На много ли?
И вообще не факт после оптимизации..
0
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
08.02.2013, 13:44 33
Вот в этом примере у меня получилось 20.5 сек против 15 в пользу массивов
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    valarray<double> V1(10000000);
    valarray<double> V2(10000000);
    valarray<double> V3(10000000);
    int N=GetTickCount();
    for(int n=0; n<100; n++)
    {   for(int i = 1; i <= 10000000; i++)
        {
            V1[i] = 1;
            V2[i] = V1[i];
            V3[i] = V2[i];
            V1[i] = 1;
            V2[i] = V1[i];
            V3[i] = V2[i];
            V1[i] = 1;
            V2[i] = V1[i];
            V3[i] = V2[i];
            V1[i] = 1;
            V2[i] = V1[i];
            V3[i] = V2[i];
            V1[i] = 1;
            V2[i] = V1[i];
            V3[i] = V2[i];
            V1[i] = 1;
            V2[i] = V1[i];
            V3[i] = V2[i];
            V1[i] = 1;
            V2[i] = V1[i];
            V3[i] = V2[i];
            V1[i] = 1;
            V2[i] = V1[i];
            V3[i] = V2[i];
            V1[i] = 1;
            V2[i] = V1[i];
            V3[i] = V2[i];
            V1[i] = 1;
            V2[i] = V1[i];
            V3[i] = V2[i];
        }
    }
    ShowMessage(GetTickCount()-N);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
    double* V1=new double[10000000];
    double* V2=new double[10000000];
    double* V3=new double[10000000];
    int N=GetTickCount();
    for(int n=0; n<100; n++)
    {   for(int i = 1; i <= 10000000; i++)
        {
            V1[i] = 1;
            V2[i] = V1[i];
            V3[i] = V2[i];
            V1[i] = 1;
            V2[i] = V1[i];
            V3[i] = V2[i];
            V1[i] = 1;
            V2[i] = V1[i];
            V3[i] = V2[i];
            V1[i] = 1;
            V2[i] = V1[i];
            V3[i] = V2[i];
            V1[i] = 1;
            V2[i] = V1[i];
            V3[i] = V2[i];
            V1[i] = 1;
            V2[i] = V1[i];
            V3[i] = V2[i];
            V1[i] = 1;
            V2[i] = V1[i];
            V3[i] = V2[i];
            V1[i] = 1;
            V2[i] = V1[i];
            V3[i] = V2[i];
            V1[i] = 1;
            V2[i] = V1[i];
            V3[i] = V2[i];
            V1[i] = 1;
            V2[i] = V1[i];
            V3[i] = V2[i];
        }
    }
    ShowMessage(GetTickCount()-N);
    delete[] V1;
    delete[] V2;
    delete[] V3;
}
1
Почетный модератор
Эксперт С++
5850 / 2861 / 392
Регистрация: 01.11.2011
Сообщений: 6,907
08.02.2013, 13:47  [ТС] 34
Цитата Сообщение от Avazart Посмотреть сообщение
Работал по тому что то массив, а не указатель на массив
Имя массива это и есть указатель на его первый элемент. Или нет?

Цитата Сообщение от Avazart Посмотреть сообщение
Во первых массив удаляют delete[] а не просто delete.
Запомнили.
Цитата Сообщение от Avazart Посмотреть сообщение
Во вторых после удаления mas продолжает указывать туда где раньше были данные, которых теперь нет
( то есть они могут и дальше там лежать а могут и нет т.е. - мусор )
Да. Все так. mas = NULL это просто защита от собственных ошибок.
0
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
08.02.2013, 13:56 35
Если в моем примере который я написал выше, поменять double на int, то выигрыш становится еще существеннее 12сек против 7.5 в пользу массивов
0
Почетный модератор
Эксперт С++
5850 / 2861 / 392
Регистрация: 01.11.2011
Сообщений: 6,907
04.04.2013, 15:12  [ТС] 36
А ведь есть еще оператор new[]. Но по умолчанию компилятор сам распознает и вставляет его на место обяного new.
1
347 / 292 / 37
Регистрация: 23.03.2012
Сообщений: 838
09.09.2013, 11:19 37
Цитата Сообщение от gumi250 Посмотреть сообщение
массивы быстрее
Можно вообще на ассемблер перейти. Что случится с памятью, выделенной под V1, если при выделении V2\V3 выскочит какой-то ексепшн? В случае с контейнерами она освободится, а в случае с массивами?
0
09.09.2013, 11:19
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.09.2013, 11:19
Помогаю со студенческими работами здесь

Удаление динамического массива с сохранением его значений
как в функции add удалить дин массив ptzz но при этом оставить его значения в ptz? #include...

Создание динамического массива и его заполнение
как можно создать динамический массив чтобы пользователь сам ввел размерность и заполнил его? вот...

Создание динамического массива и его обработка
Сформировать одномерный массив. Удалить из него элемент с заданным номером, добавить К элементов,...

Ошибка, создание динамического массива и его вывод
есть часть кода всей программы , выполняется неверно или вообще не выполняется... в чем ошибка...

Создание динамического массива строк и его сортировка
Как создать динамический массив строк в Си и отсортировать его?

Создание динамического массива и его инициализация в конструкторе класса
A1uk, ПравилаИзначальное название темы: &quot;Помогите исправить код&quot;. Доброго времени суток. Помоги...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
37
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru