Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Realloc в С++, чем плохо  
V
    Опции темы
sergioK1
Дата 6.3.2012, 17:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 417
Регистрация: 30.1.2011

Репутация: нет
Всего: нет



Слышу что плохо , а в чем ?, ну есть вектор, ну он же не вместо realloc, по крайне мере в доках никто не говорит что он лучше,
Или Я чего не понимаю?


PM MAIL   Вверх
borisbn
Дата 6.3.2012, 18:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Цитата(sergioK1 @  6.3.2012,  17:35 Найти цитируемый пост)
Слышу что плохо , а в чем ?

1) Как минимум realloc не типизирован (читай увеличивается вероятность ошибки).
2) Вместе с указателем на память, выделенную malloc/realloc неплохо бы хранить выделенный размер. У вектора это есть нахаляву
3) При удалении вектора он сам следит за освобождением выделенной им памяти, в случае с malloc/realloc программист должен не забыть вызвать free когда память больше не нужна

на самом деле пунктов больше... я тебе только основные привёл


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
bsa
Дата 6.3.2012, 20:47 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



самый главный забыл.

если у тебя объекты содержат ссылки/указатели на другие объекты в том же массиве, то после realloc возможна ситуация, что размещение массива в памяти изменится, а вот указатели/ссылки внутри объектов нет. В итоге это приведет к серьезным ошибкам. Именно поэтому в С++ realloc нежелателен.
PM   Вверх
volatile
Дата 6.3.2012, 23:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(bsa @  6.3.2012,  20:47 Найти цитируемый пост)
если у тебя объекты содержат ссылки/указатели на другие объекты в том же массиве, то после realloc возможна ситуация, что размещение массива в памяти изменится

Между прочим с вектором картина в точности такая-же.
Так что здесь проблема скорей в ссылках и указателях.
PM MAIL   Вверх
sergioK1
Дата 7.3.2012, 01:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 417
Регистрация: 30.1.2011

Репутация: нет
Всего: нет



Цитата(bsa @ 6.3.2012,  19:47)
самый главный забыл.

если у тебя объекты содержат ссылки/указатели на другие объекты в том же массиве, то после realloc возможна ситуация, что размещение массива в памяти изменится, а вот указатели/ссылки внутри объектов нет. В итоге это приведет к серьезным ошибкам. Именно поэтому в С++ realloc нежелателен.

как это измениться ? 

man 3 realloc 

 void *realloc(void *ptr, size_t size);

realloc() changes the size of the memory block pointed  to  by  ptr  to
       size  bytes.   The contents will be unchanged to the minimum of the old
       and new sizes; newly allocated memory will be uninitialized.  If ptr is
       NULL,  then  the  call is equivalent to malloc(size), for all values of
       size; if size is equal to zero, and ptr is not NULL, then the  call  is
       equivalent  to  free(ptr).   Unless  ptr  is  NULL,  it  must have been
       returned by an earlier call to malloc(), calloc() or realloc().  If the
       area pointed to was moved, a free(ptr) is done.


 где тут сказано про то что размешение измениться ,?



borisbn 

 для стандартных задач это хорошо,
ну а если свой вектор нужен , самое простое перед функцией resize - запись в лог, или мютекс ,?
и есть типы обьестов которые надо закрыть ? 
 
то наследовать? обертку писать ? ну тогда твой класс должен быть темплайтным , 
У меня свой контейнер , и Я счас не знаю что лучше realloc или новый malloc + memcpy + заполнение второй части данными,
Я с этим столькнулся в 99 году на чистом С(Win32),  realloc из-за  падал и пришлось  менять логику что-бы без него , 
там что то обьяснялось ,только Я не помню

С тех пор наверно что-то изменилось ? 





 
 




PM MAIL   Вверх
volatile
Дата 7.3.2012, 01:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(sergioK1 @  7.3.2012,  01:12 Найти цитируемый пост)
где тут сказано про то что размешение измениться ,?


sergioK1, Как вы себе вообще это представляете? Произвольное изменение размера, непрерывного участка памяти ?

Цитата

The function may move the memory block to a new location, in which case the new location is returned. 

realloc
PM MAIL   Вверх
sergioK1
Дата 7.3.2012, 04:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 417
Регистрация: 30.1.2011

Репутация: нет
Всего: нет



Цитата(volatile @ 7.3.2012,  00:58)
Цитата(sergioK1 @  7.3.2012,  01:12 Найти цитируемый пост)
где тут сказано про то что размешение измениться ,?


sergioK1, Как вы себе вообще это представляете? Произвольное изменение размера, непрерывного участка памяти ?

Цитата

The function may move the memory block to a new location, in which case the new location is returned. 

realloc

Xm почему в доке Линукса ничего про это не сказано ?
хотя простой тест показал что это так,

чего то Я не понимаю,  блок памяти передвиниться а ссылки эти разве не в нем? ,  т,е элемент массива это стуктура , где первый 
элемент это его начало , и все ссылки внутри что с ними будет ?
если скажем первый элемент массива имеет ссылку на скажем 8-ой тогда да realloc даст сбой , но в каком случае, изначально 
создавать такой массив архитектурная ошибка IMHO, или задача специфичная, 
и потом элементы могут меняться , кто за ссылками следить будет ?

да и какая разница С или С++? 
PM MAIL   Вверх
borisbn
Дата 7.3.2012, 06:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



>обертку писать ? ну тогда твой класс должен быть темплайтным
Абсолютно ничего плохого здесь не вижу.   
>да и какая разница С или С++?
тут 2 момента: 1) ты задал вопрос именно про Си++ 2) в Си просто нет вектора, new/delete и т.п., поэтому в Си кроме realloc'а ничего и не остаётся. 




--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Dem_max
Дата 7.3.2012, 06:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 4
Всего: 39



в С++ есть только new и delete.


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
LeonidPr
Дата 7.3.2012, 07:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 220
Регистрация: 17.2.2012
Где: г. Чебоксары

Репутация: нет
Всего: 1



Цитата(sergioK1 @ 7.3.2012,  01:12)
...где тут сказано про то что размешение измениться ,?

Здесь
Цитата

The size of the memory block pointed to by the ptr parameter is changed to the size bytes, expanding or reducing the amount of memory available in the block.

The function may move the memory block to a new location, in which case the new location is returned. The content of the memory block is preserved up to the
lesser of the new and old sizes, even if the block is moved. If the new size is larger, the value of the newly allocated portion is indeterminate.

In case that ptr is NULL, the function behaves exactly as malloc, assigning a new block of size bytes and returning a pointer to the beginning of it.

In case that the size is 0, the memory previously allocated in ptr is deallocated as if a call to free was made, and a NULL pointer is returned.

--------------------
pkunzip.zip
PM MAIL   Вверх
bsa
Дата 7.3.2012, 10:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(volatile @  7.3.2012,  00:24 Найти цитируемый пост)
Между прочим с вектором картина в точности такая-же.
Так что здесь проблема скорей в ссылках и указателях. 

Вообще-то вектор копирует содержимое не с помощью memcpy, а с использованием операторов копирования. Поэтому, если класс более или менее вменяемый, то он это дело сам разрулит.
PM   Вверх
sergioK1
Дата 7.3.2012, 11:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 417
Регистрация: 30.1.2011

Репутация: нет
Всего: нет



Цитата(borisbn @ 7.3.2012,  05:19)
>обертку писать ? ну тогда твой класс должен быть темплайтным
Абсолютно ничего плохого здесь не вижу.   
>да и какая разница С или С++?
тут 2 момента: 1) ты задал вопрос именно про Си++ 2) в Си просто нет вектора, new/delete и т.п., поэтому в Си кроме realloc'а ничего и не остаётся.

Да нет, Я говорю не про вектор , это отдельная тема , 

Случайно ++ добавил ,  
Я про realloc vs новый malloc  c переписыванием всего старого массива в новый , 

 т,е, способ 1 
Код

  
     int* arr= (int*) malloc(20* sizeof(int))
     int* arr1 = (int*)realloc(arr, 15*sizeof(int) ;
    for(int i=0;i< 15; i++) 
      arr1[20+i] = новым значениям 


 или 
Код

            int* arr= (int*) malloc(20* sizeof(int))
     int* arr1 = (int*) malloc((20+15)*sizeof(int) ;
     memcpy(arr1,arr,20) ;
    for(int i=0;i< 15; i++) 
      arr1[20+i] = новым значениям 


  
   вместо int* могут быть обьекты AnyClass* object , разница тоько что в С++ typedef не нужен и в С есть только   Struct.
   т,е, чем плохо Я имел ввиду разницу между этими способами, какая разница С или С++?

   
   
bsa :

какая разница что оператор копирования ,это тот же memcopy, только скрыиый, релизации на все равно на асемблере , другово еще не придумали smile 
  

Это сообщение отредактировал(а) sergioK1 - 7.3.2012, 14:53
PM MAIL   Вверх
xvr
Дата 7.3.2012, 15:40 (ссылка) |    (голосов:4) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(sergioK1 @  7.3.2012,  11:30 Найти цитируемый пост)
какая разница что оператор копирования ,это тот же memcopy, 

Оператор копирования - это operator =() и копируемый класс его может переопределить, если это надо (а это часто надо)

Цитата(sergioK1 @  7.3.2012,  11:30 Найти цитируемый пост)
релизации на все равно на асемблере , другово еще не придумали 

Как все запущено  smile 

PM MAIL   Вверх
sergioK1
Дата 7.3.2012, 17:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 417
Регистрация: 30.1.2011

Репутация: нет
Всего: нет



Цитата(xvr @ 7.3.2012,  14:40)

Оператор копирования - это operator =() и копируемый класс его может переопределить, если это надо (а это часто надо)

 Это как бы все знают ,
И что , это всего  лишь для удобсва ,  легче писать , 
А как он реализован? И чем скомилированный код с ним отличаеться от того что без ?

PM MAIL   Вверх
xvr
Дата 7.3.2012, 17:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(sergioK1 @  7.3.2012,  17:00 Найти цитируемый пост)
И чем скомилированный код с ним отличаеться от того что без ?

Отличаться может координально. Вплоть до того, что memcpy работать для данного класса не будет, а operator =() будет.
Например:
Код

class String {
 char buffer[1024];
 char* last_ptr; // Where 'buffer' ends
public:
 String()
  {
   last_ptr=buffer;
  }

 void append(const char* str)
  {
   strcpy(last_ptr,str);
   last_ptr+=strlen(past_ptr);
  }

 void operator=(const String& s)
  {
   memcpy(buffer,s.buffer,sizeof(buffer));
   last_ptr=buffer+(s.last_ptr-s.buffer);
  }
};

Без operator=() этот класс после копирования начнет дописывать строки к оригиналу (откуда копировали), а не к себе.

PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0721 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.