Форум программистов, компьютерный форум CyberForum.ru

как освободить только первый элемент массива, не трогая остальные? - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.67
Ksan
26 / 26 / 0
Регистрация: 02.11.2010
Сообщений: 370
09.06.2012, 21:26     как освободить только первый элемент массива, не трогая остальные? #1
Есть код:

C
1
2
int *ptr;
ptr = (int*)calloc(10, sizeof(int));
собственно вопрос: как освободить только первый элемент массива? не трогая остальные
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.06.2012, 21:26     как освободить только первый элемент массива, не трогая остальные?
Посмотрите здесь:

C++ Дан массив F[0:n-1].Сформировать два новых массива: первый содержит элементы, не превышающие заданного числа, а второй - все остальные
C++ Как удалить из одномерного массива первый отрицательный элемент
Создать два новых массива: в первый перенести все цифры из исходного массива, во второй - все остальные символы C++
C++ Сформировать два массива из исходного: в первый записать отрицательные элементы, во второй – остальные
Как определить первый с конца четный элемент двумерного массива? C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
AnyOne697
 Аватар для AnyOne697
134 / 106 / 5
Регистрация: 22.05.2010
Сообщений: 532
09.06.2012, 21:36     как освободить только первый элемент массива, не трогая остальные? #2
В Си - никак. В Си++ подозреваю, можно использовать delete, вместо delete []. Не проверял.

Добавлено через 2 минуты
Впрочем, если используется динамическая структура, где каждый отдельный элемент имеет свой кусок памяти - то... Ну, в общем, понятно. Деревья, списки и прочее поддаются гуглению.
Avazart
 Аватар для Avazart
6905 / 5145 / 253
Регистрация: 10.12.2010
Сообщений: 22,630
Записей в блоге: 17
09.06.2012, 21:38     как освободить только первый элемент массива, не трогая остальные? #3
как освободить только первый элемент массива? не трогая остальные
Так просто не делают... если и освобождают так весь массив....
Ksan
26 / 26 / 0
Регистрация: 02.11.2010
Сообщений: 370
09.06.2012, 21:41  [ТС]     как освободить только первый элемент массива, не трогая остальные? #4
AnyOne697, new\delete не умеют довыделять память.

хорошо, а насколько корректна следующая запись?

C
1
2
3
4
5
6
7
int *ptr, *ptr2;
        ptr = (int*)calloc(10, 4);
        for(int i=0; i<10; ++i) ptr[i] = i;
        ptr2 = ptr;
        ptr += 9;
        free(ptr);
        ptr = ptr2;
AnyOne697
 Аватар для AnyOne697
134 / 106 / 5
Регистрация: 22.05.2010
Сообщений: 532
09.06.2012, 21:51     как освободить только первый элемент массива, не трогая остальные? #5
Хм... Не корректна. Вообще. http://codepad.org/zhxvKdfH (смысл тот же).
MikeSoft
Эксперт C++
 Аватар для MikeSoft
3782 / 1766 / 85
Регистрация: 21.11.2009
Сообщений: 2,540
09.06.2012, 21:58     как освободить только первый элемент массива, не трогая остальные? #6
Цитата Сообщение от Ksan Посмотреть сообщение
AnyOne697, new\delete не умеют довыделять память.
А написать функцию, возвращающую указатель на "нововыделенную" область памяти (с новым указанным размером) разве не сможете?

Вам правильно советуют:
Цитата Сообщение от AnyOne697 Посмотреть сообщение
В Си - никак. В Си++ подозреваю, можно использовать delete, вместо delete [].
Ksan
26 / 26 / 0
Регистрация: 02.11.2010
Сообщений: 370
09.06.2012, 22:01  [ТС]     как освободить только первый элемент массива, не трогая остальные? #7
Цитата Сообщение от MikeSoft Посмотреть сообщение
А написать функцию, возвращающую указатель на "нововыделенную" область памяти (с новым указанным размером) разве не сможете?
Не совсем понял, что вы имеете ввиду под этим?
Мне 2мя указателями оперировать что ли?
Jtalk
93 / 79 / 4
Регистрация: 13.05.2011
Сообщений: 279
09.06.2012, 22:08     как освободить только первый элемент массива, не трогая остальные? #8
Цитата Сообщение от MikeSoft Посмотреть сообщение
Вам правильно советуют:
А как потом доудалить оставшуюся?

Топикстартер, C плохо работает с массивами. Если нужен именно он, то либо realloc, что адски медленно, либо сделать новый указатель, да. Если память нужно будет удалять, то сохранить оригинальный — удаление по измененному указателю, если я правильно помню, работает некорректно.
AnyOne697
 Аватар для AnyOne697
134 / 106 / 5
Регистрация: 22.05.2010
Сообщений: 532
09.06.2012, 22:16     как освободить только первый элемент массива, не трогая остальные? #9
Цитата Сообщение от Ksan Посмотреть сообщение
Не совсем понял, что вы имеете ввиду под этим?
Мне 2мя указателями оперировать что ли?
Цитата Сообщение от MikeSoft Посмотреть сообщение
А написать функцию, возвращающую указатель на "нововыделенную" область памяти (с новым указанным размером) разве не сможете?
Примерно так:
C++
1
2
3
4
5
6
char *realloc(char *p, unsigned size){
   char *t = new char[size];
   memset(t, p, size);
   delete [] p;
   return t;
}

Цитата Сообщение от Jtalk Посмотреть сообщение
А как потом доудалить оставшуюся?
Легко. Указатель не обнуляется.
C++
1
2
3
4
5
6
int main(){
   int *a = new int[12];
   delete a++; //была освобождена память для первого элемента
 
   return 0;
}
Впрочем, я не уверен в возможности сего. Когда использовал, утечек не наблюдалось. Но использовал в небольшой программе - просто хотел немного оптимизировать.

Цитата Сообщение от Jtalk Посмотреть сообщение
C плохо работает с массивами
Сложность работы с ними не обуславливает плохую работу. Си просто идеально работает с массивами. Кроме массивов в Си просто ничего нет ;-)
Ksan
26 / 26 / 0
Регистрация: 02.11.2010
Сообщений: 370
09.06.2012, 22:16  [ТС]     как освободить только первый элемент массива, не трогая остальные? #10
Jtalk, realloc медленно работает? вы уверены?
Jtalk
93 / 79 / 4
Регистрация: 13.05.2011
Сообщений: 279
09.06.2012, 22:22     как освободить только первый элемент массива, не трогая остальные? #11
Цитата Сообщение от AnyOne697 Посмотреть сообщение

Легко. Указатель не обнуляется.
Код C++1 2 3 4 5 6 int main(){ int *a = new int[12]; delete a++; //была освобождена память для первого элемента return 0; }
Впрочем, я не уверен в возможности сего. Когда использовал, утечек не наблюдалось. Но использовал в небольшой программе - просто хотел немного оптимизировать.
В данном случае память очистит ОС после закрытия приложения. В стандарте C++ (по крайней мере старом) четко было написано, что модифицировать указатель, выданный new[], нельзя, т.к. это вызовет ошибки при использовании delete[]. Соответственно, удалять память "кусками" можно только если приложение маленькое и небольшие утечки не страшны.


Сложность работы с ними не обуславливает плохую работу. Си просто идеально работает с массивами. Кроме массивов в Си просто ничего нет ;-)
структуры, перечисления, объединения, функции, etc.
А как еще обозначить плохую работу? Что угодно можно сделать библиотеками, удобство работы с массивами — это в первую очередь качество их поддержки языком. А C дальше указателей на память массивы никогда не поддерживал.

Добавлено через 1 минуту
Цитата Сообщение от Ksan Посмотреть сообщение
Jtalk, realloc медленно работает? вы уверены?
По сравнению с инкрементом указателя? На порядки. realloc просто выделяет новый кусок памяти и делает memcpy куска старой памяти в новую. Соответственно, замедление зависит от объема выделяемой и копируемой памяти. Насколько я помню, realloc не умеет оптимизировать этот процесс.
Ksan
26 / 26 / 0
Регистрация: 02.11.2010
Сообщений: 370
09.06.2012, 22:27  [ТС]     как освободить только первый элемент массива, не трогая остальные? #12
Jtalk, я думал, что реаллок выделяет кусок памяти и "клеит" его к старому
Jtalk
93 / 79 / 4
Регистрация: 13.05.2011
Сообщений: 279
09.06.2012, 22:30     как освободить только первый элемент массива, не трогая остальные? #13
Цитата Сообщение от Ksan Посмотреть сообщение
Jtalk, я думал, что реаллок выделяет кусок памяти и "клеит" его к старому
Сейчас посмотрел, да, он может так делать. Но это не гарантируется. Да и вам надо "отклеить".
Chelioss
179 / 179 / 4
Регистрация: 08.01.2011
Сообщений: 1,131
09.06.2012, 22:43     как освободить только первый элемент массива, не трогая остальные? #14
Цитата Сообщение от AnyOne697 Посмотреть сообщение
Легко. Указатель не обнуляется.
C++
1
2
3
4
5
6
int main(){
   int *a = new int[12];
   delete a++; //была освобождена память для первого элемента
 
   return 0;
}
Такой вопрос:
C++
1
2
3
4
5
6
int main(){
   int *a = new int[12];
   delete a++; //была освобождена память для первого элемента
   delete [] a;
   return 0;
}
Как система узнает, что надо удалить 11 элементов начиная с адреса a?
AnyOne697
 Аватар для AnyOne697
134 / 106 / 5
Регистрация: 22.05.2010
Сообщений: 532
09.06.2012, 22:46     как освободить только первый элемент массива, не трогая остальные? #15
Цитата Сообщение от Chelioss Посмотреть сообщение
Как система узнает, что надо удалить 11 элементов начиная с адреса a?
Она вывалит exception. Так что надо будет в цикле удалять по одному. Ранее уже говорилось, что это чревато утечками. Если программа небольшая (пару сотен килобайт) - ОС сама освободит память после завершения работы.

А вообще, преждевременная оптимизация - корень всех зол.
Chelioss
179 / 179 / 4
Регистрация: 08.01.2011
Сообщений: 1,131
09.06.2012, 22:50     как освободить только первый элемент массива, не трогая остальные? #16
Цитата Сообщение от AnyOne697 Посмотреть сообщение
Она вывалит exception.
Неопределенное поведение.
Цитата Сообщение от AnyOne697 Посмотреть сообщение
Так что надо будет в цикле удалять по одному.
Недостаточно. В смысле не все освободиться.

Цитата Сообщение от AnyOne697 Посмотреть сообщение
Если программа небольшая (пару сотен килобайт) - ОС сама освободит память после завершения работы.
А если большая, то не освободит?
Jupiter
Каратель
Эксперт C++
6543 / 3963 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
10.06.2012, 22:46     как освободить только первый элемент массива, не трогая остальные? #17
Цитата Сообщение от AnyOne697 Посмотреть сообщение
В Си++ подозреваю, можно использовать delete, вместо delete []. Не проверял.
да за такое надо наказывать. жестоко наказывать - это же UB
 Комментарий модератора 
Прекращаем оффтоп!
AnyOne697
 Аватар для AnyOne697
134 / 106 / 5
Регистрация: 22.05.2010
Сообщений: 532
11.06.2012, 19:16     как освободить только первый элемент массива, не трогая остальные? #18
Цитата Сообщение от Jupiter Посмотреть сообщение
да за такое надо наказывать. жестоко наказывать - это же UB
Я сначала обиделся за вырезанные сообщения, но потом понял, что Вы ещё что-то добавили...

Только вот пояснить забыли. Если удалить весь массив через цикл - утечек быть не должно. Вывод - если требуется более продвинутая (читай, удобная) модель менеджмента памяти - делаем её сами. За что наказывать-то?
Jupiter
Каратель
Эксперт C++
6543 / 3963 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
11.06.2012, 20:19     как освободить только первый элемент массива, не трогая остальные? #19
Цитата Сообщение от AnyOne697 Посмотреть сообщение
Только вот пояснить забыли. Если удалить весь массив через цикл - утечек быть не должно. Вывод - если требуется более продвинутая (читай, удобная) модель менеджмента памяти - делаем её сами. За что наказывать-то?
отвечаю:
5.3.5 Delete
1
[expr.delete]
The delete-expression operator destroys a most derived object (1.8) or array created by a new-expression.
delete-expression:
::opt delete cast-expression
::opt delete [ ] cast-expression
The first alternative is for non-array objects, and the second is for arrays. The operand shall have a pointer
type, or a class type having a single conversion function (12.3.2) to a pointer type. The result has type
void.
2 If the operand has a class type, the operand is converted to a pointer type by calling the above-mentioned
conversion function, and the converted operand is used in place of the original operand for the remainder of
this section. In either alternative, if the value of the operand of delete is the null pointer the operation
has no effect. In the first alternative (delete object), the value of the operand of delete shall be a pointer
to a non-array object or a pointer to a sub-object (1.8) representing a base class of such an object (clause
10). If not, the behavior is undefined. In the second alternative (delete array), the value of the operand of
delete shall be the pointer value which resulted from a previous array new-expression.72) If not, the
behavior is undefined.
[Note: this means that the syntax of the delete-expression must match the type of the object allocated by new, not the syntax of the new-expression. ] [Note: a pointer to a const type can be
the operand of a delete-expression; it is not necessary to cast away the constness (5.2.11) of the pointer
expression before it is used as the operand of the delete-expression. ]
стандарт С++ от 2003
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.06.2012, 00:47     как освободить только первый элемент массива, не трогая остальные?
Еще ссылки по теме:

Поменять местами минимальный элемент и первый отрицательный элемент массива целых чисел C++
C++ Проверить, упорядочены ли элементы, заменить первый нулевой элемент и удалить указанный элемент из массива
Выводится в файл только первый символ строки, остальные пустые C++

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

Или воспользуйтесь поиском по форуму:
AnyOne697
 Аватар для AnyOne697
134 / 106 / 5
Регистрация: 22.05.2010
Сообщений: 532
12.06.2012, 00:47     как освободить только первый элемент массива, не трогая остальные? #20
Хм. А Вы возможно забыли тот факт, что ни GCC ни Visual C++ полностью стандарту не соответствуют. Поэтому в первую очередь RTFM, а затем, j4f, RTFS.
Хотя да. Почитал Интернеты, вот пара линков. Правда неопределённое поведение. И ещё. Здесь подраздел "... для новичков". Поэтому не стоит кидать непереведённый стандарт, английский вообще и тем более: важные в контексте сленговые аббревиатуры-сокращения. Просто потому что, я, например, понятия не имел что есть "UB", но должен был понять для понимания причины, по которой меня должны наказать.
P.S. Самый Главный Линк
Yandex
Объявления
12.06.2012, 00:47     как освободить только первый элемент массива, не трогая остальные?
Ответ Создать тему
Опции темы

Текущее время: 16:38. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru