LINUX.ORG.RU

realloc()


0

0

есть указатель на массив, под массив выделаю память с помощью calloc(). работаю с массивом, после чего выясняется, что размер массива недостаточен и его нужно увеличить. в описании на realloc говорится, что эта функция увеличивает размер не повреждая и не изменяя старые данные, я правильно понял ? и все же есть какая-либо вероятность, что старые данные будут повреждены ? уж больно не хочится делать промежуточные буферы.

anonymous

ничего не тронется до наименьшей длины из старой и новой .. только учти что в
calloc() ты подавал еще размер объекта .. а в realloc() размер указывается в
байтах .. такчто лучше(чтобы не путать себя и других) делай так [ хотя это не
принципиально ]:

m = (obj**)malloc(nobjs * sizeof(obj)); /* вместо m = (obj**)calloc(nobjs, sizeof(obj); */
...
...
if (not_enought && new_nobjs > nobjs)
   m = (obj**)realloc(new_nobjs * sizeof(obj));

lg ★★
()

2 lg > m = (obj**)malloc(nobjs * sizeof(obj)); Знаете, какое самое частотное выражение на comp.lang.c после ``off topic'' и ``int main()''? *Never* cast a malloc... ;)

aa5779
()

2aa5779: cum get some?
знаете какой самый чатый ответ на выражение "*Never* cast a malloc" в freebsd-hackers?

твое мнение про кастинг лишь правильно в "не правильном" реализации malloc() когда у тебя malloc info хранится _перед_ малочнутыми данными - например КАК ЭТО ТУПО использовать перед малочнутыми данными какую то инфу об этом маллоке .. во первых это позволяет иметь место всяким malloc-overflow exploits .. когда ты можешь переписать инфу о маллокнутых данных .... во-вторых почему бы не хранить всю эту инфу о чанках в отдельном месте как это длается в FreeBSD например?

как ты думаешь какой контингент подписан на comp.lang.c исключая любителей читать offtopics?

lg ★★
()

Я что-то не понял, ребята, приводить cast-ом при malloc-е не рекомендуется в Линухе? Я пишу прогу, которая активно работает с хипом, причём пишу под фрями, тестирую тоже под ними. Естественно делаю cast: (char*)malloc(..) и т.д. И вы хотите сказать, что под Линухом оно будет работать совсем не так, т.е. вообще может не работать?

anonymous
()

2anonym: все нормально .. делай cast - это просто дело вкуса и в некоторых местах глюкаловка .. но в обычных случаях все ок

lg ★★
()

2 lg,aa5779:

8-/?

Не въехал...

ПОЧЕМУ нельзя приводить malloc()?

Чем приведение malloc()'а отличается от приведения void* ?

lg (*) (2002-11-30 01:55:36.141):
Details? -- Ни хрена не понял :(
Можешь помедленнее и - по-русски (вариант - по английски)?

Die-Hard ★★★★★
()

2Die-Hard: насколько я знаю (если где ошибаюсь - поправляйте)
malloc() в Linux устроен слудующим образом:

когда ты вызываешь int *r; r = malloc(n)
выделяется какой то кусок памяти - например длиной 8+n+3 байт

malloc chunk:
+------+---------------+-----
|8bytes| n bytes len | pad
+------+---------------+-----
malloc /\ данные
info ||
r
---- full len ---------

в зависимости от настроик маллока full len должен быть кратен 2 или 4 или 8 или еще чему
сделав r -= 2; *r++ = 0; *r = 0; free(r) - получится кал ..


во freebsd malloc() устроен немного подругому - сначала malloc() инициализируется выделяя какой то конкретный кусок памяти .. например длиной 1024 байт в этом куске он и будет искать malloc info (информацию о маллокнутых чанках) которая в Линуксятском находится прямо перед данными
malloc info table:
+-+----
|1| malloc info, data pointer=0x8040001
+-+-----
|2| malloc info, data pointer=0x8050000
....
|n| ...

malloc chunk:
+-----------+------
| n bytes | pad
+-----------+------

к кастингу это имеет весьма слабое отношение - я в предыдущем посте не совсем корректно высказался, получилось так что как будто бы кастинг маллока может привести к каким то проблемам (кстати возможно это так и есть [не в курсе, но помоему что то такое пробегало как-то])

про кастинг - так вот мне кажется что гораздо лучше приучать себя писать:
int *p;
p = (int*)malloc(n) + 4;
нежели
p = malloc(n) + ??;

варианта по английски не знаю .. :(

lg ★★
()
Ответ на: комментарий от lg

lg (*) (2002-11-30 19:27:18.497):
> r -= 2; *r++ = 0; *r = 0; free(r) - получится кал ..
Не удивительно!

> int *p;
> p = malloc(n) + ??;
Удивительно, что такое вообще проходит...
IMHO адресная арифметика с void указателем - глупость, подлежащая отлову
компилятором. Но, как я понял, стандарты требуют?

Вот шедевр:
int *p0,*p1,*p2;
void *qq0,*qq1,*qq2;
p0=(qq0=malloc(4))+4;
p2=( (p1=malloc(4))+4 );
qq1=(malloc(4)+4);
qq2=qq1+4;
printf(" %p %p\n %p %p\n %p %p\n",qq0,p0,p1,p2,qq1,qq2);


0x8049660 0x8049664
0x8049670 0x8049680
0x8049684 0x8049688

Die-Hard ★★★★★
()

>> r -= 2; *r++ = 0; *r = 0; free(r)
> Не удивительно!
я понял - под пиво писать не катируется :)
имелось ввиду
r -= 2; *r++ = 0; *r++ = 0; free(r);
для меня удивительно что после этого будет segfault, замечу еще раз что под FreeBSD chunks info в другом месте - поэтому все пучком будет (должно быть)
не проверял

с дальнейшим - единодушен полностью

lg ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.