Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.91/11: Рейтинг темы: голосов - 11, средняя оценка - 4.91
27 / 27 / 4
Регистрация: 02.11.2010
Сообщений: 370
1

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

09.06.2012, 21:26. Показов 2305. Ответов 20
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Есть код:

C
1
2
int *ptr;
ptr = (int*)calloc(10, sizeof(int));
собственно вопрос: как освободить только первый элемент массива? не трогая остальные
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.06.2012, 21:26
Ответы с готовыми решениями:

Первый элемент массива равен 1 а остальные почему-то нулю
Здраствуйте есть вопрос к задаче: дана программу реализовывающую вычисление последовательности...

Выводит только первый элемент массива символов
Потом вместо каждого символа выводит что-то вроде |for (int i = 0; i < 100; i++) { ...

Ошибка: Выводится только первый элемент массива
выводит только первый элемент. Подскажите пожалуйста, как исправить? char* massivImpl::outmass()...

Как отформатировать второй диск не трогая первый?
В общем такая история... остался хард от старого компа с установленной на нем виндой и он разбит на...

20
134 / 106 / 10
Регистрация: 22.05.2010
Сообщений: 533
09.06.2012, 21:36 2
В Си - никак. В Си++ подозреваю, можно использовать delete, вместо delete []. Не проверял.

Добавлено через 2 минуты
Впрочем, если используется динамическая структура, где каждый отдельный элемент имеет свой кусок памяти - то... Ну, в общем, понятно. Деревья, списки и прочее поддаются гуглению.
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
09.06.2012, 21:38 3
как освободить только первый элемент массива? не трогая остальные
Так просто не делают... если и освобождают так весь массив....
0
27 / 27 / 4
Регистрация: 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;
0
134 / 106 / 10
Регистрация: 22.05.2010
Сообщений: 533
09.06.2012, 21:51 5
Хм... Не корректна. Вообще. http://codepad.org/zhxvKdfH (смысл тот же).
0
Эксперт С++
3953 / 1808 / 184
Регистрация: 21.11.2009
Сообщений: 2,540
09.06.2012, 21:58 6
Цитата Сообщение от Ksan Посмотреть сообщение
AnyOne697, new\delete не умеют довыделять память.
А написать функцию, возвращающую указатель на "нововыделенную" область памяти (с новым указанным размером) разве не сможете?

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

Топикстартер, C плохо работает с массивами. Если нужен именно он, то либо realloc, что адски медленно, либо сделать новый указатель, да. Если память нужно будет удалять, то сохранить оригинальный — удаление по измененному указателю, если я правильно помню, работает некорректно.
0
134 / 106 / 10
Регистрация: 22.05.2010
Сообщений: 533
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 плохо работает с массивами
Сложность работы с ними не обуславливает плохую работу. Си просто идеально работает с массивами. Кроме массивов в Си просто ничего нет ;-)
0
27 / 27 / 4
Регистрация: 02.11.2010
Сообщений: 370
09.06.2012, 22:16  [ТС] 10
Jtalk, realloc медленно работает? вы уверены?
0
95 / 81 / 3
Регистрация: 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 не умеет оптимизировать этот процесс.
0
27 / 27 / 4
Регистрация: 02.11.2010
Сообщений: 370
09.06.2012, 22:27  [ТС] 12
Jtalk, я думал, что реаллок выделяет кусок памяти и "клеит" его к старому
0
95 / 81 / 3
Регистрация: 13.05.2011
Сообщений: 279
09.06.2012, 22:30 13
Цитата Сообщение от Ksan Посмотреть сообщение
Jtalk, я думал, что реаллок выделяет кусок памяти и "клеит" его к старому
Сейчас посмотрел, да, он может так делать. Но это не гарантируется. Да и вам надо "отклеить".
0
186 / 186 / 21
Регистрация: 08.01.2011
Сообщений: 1,139
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?
0
134 / 106 / 10
Регистрация: 22.05.2010
Сообщений: 533
09.06.2012, 22:46 15
Цитата Сообщение от Chelioss Посмотреть сообщение
Как система узнает, что надо удалить 11 элементов начиная с адреса a?
Она вывалит exception. Так что надо будет в цикле удалять по одному. Ранее уже говорилось, что это чревато утечками. Если программа небольшая (пару сотен килобайт) - ОС сама освободит память после завершения работы.

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

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

Только вот пояснить забыли. Если удалить весь массив через цикл - утечек быть не должно. Вывод - если требуется более продвинутая (читай, удобная) модель менеджмента памяти - делаем её сами. За что наказывать-то?
0
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
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
0
134 / 106 / 10
Регистрация: 22.05.2010
Сообщений: 533
12.06.2012, 00:47 20
Хм. А Вы возможно забыли тот факт, что ни GCC ни Visual C++ полностью стандарту не соответствуют. Поэтому в первую очередь RTFM, а затем, j4f, RTFS.
Хотя да. Почитал Интернеты, вот пара линков. Правда неопределённое поведение. И ещё. Здесь подраздел "... для новичков". Поэтому не стоит кидать непереведённый стандарт, английский вообще и тем более: важные в контексте сленговые аббревиатуры-сокращения. Просто потому что, я, например, понятия не имел что есть "UB", но должен был понять для понимания причины, по которой меня должны наказать.
P.S. Самый Главный Линк
0
12.06.2012, 00:47
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
12.06.2012, 00:47
Помогаю со студенческими работами здесь

Правильно выводится только первый элемент полученного массива
char *IntToChar(long long chislo) { long long INT; int count=0; char str;...

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

Почему при создании динамического массива, отладчик видит только один первый элемент?
Здравствуйте. Объясните почему при создании динамического массива, отладчик (а точнее окно...

Поменять местами первый максимальный четный элемент массива и первый минимальный нечетный элемент
Помогите начало знаю как сделать а дальше нет #include&lt;iostream&gt; #include &lt;stdlib.h&gt; #include...


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

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