LINUX.ORG.RU

100500-й вопрос по realloc

 ,


0

1

почему в С98 и С++ realloc() пытается расширить текущий блок, и лишь в случае неудачи выделяет память на новом месте а в С99 — сразу выделяет память на новом месте?

★★★★★

Последнее исправление: cetjs2 (всего исправлений: 1)
Ответ на: комментарий от mashina

Это и есть смена философского понимания старого подхода (как что-то хорошее): физически ничего же не изменилось.

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

Раньше было точно такое же «философское понимание»

да

Нет, это корректировка текста.

одно другого не исключает

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

Может быть изданные ещё и на русском языке? Черновики стандартов (кроме выносимых на последнее голосование, а в том черновике вносятся только косметические правки) С и С++ свободно доступны с сайтов рабочих групп.

Begemoth ★★★★★
()

А я вообще думал, что этим ведро занимается: выделяет новые блоки и "приплюсовывает" их к уже выделенному объему памяти. А для glibc все как бы прозрачно. А оно, оказывается, так запущенно...

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

ведро и занимается, вы правильно думали, но в ответ на комманду от процесса, которая может быть построена по разному

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

Может быть изданные ещё и на русском языке?

не обязательно, но было бы неплохо

Черновики стандартов (кроме выносимых на последнее голосование, а в том черновике вносятся только косметические правки) С и С++ свободно доступны с сайтов рабочих групп.

и как мне их прочитать без компа?

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

Это если не учитывать всяких jemalloc или umem ;-)

anonymous
()
Ответ на: комментарий от next_time

вообще не видел ни в одной книге пачки ссылок на стандарт

Патамучто жалкие книженки пишут бездари, не?

по моим тестам реаллок быстрее, чем маллок + фри в 1,69 раза

Тесты в студию.

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

бумага+краска+скрепление+место на полке

next_time ★★★★★
() автор топика
Ответ на: комментарий от anonymous
#include "stdio.h"
#include "stdlib.h"
#include "time.h"

int main(void)
{
void *p = malloc(5);
unsigned int i;
clock_t time = clock();
for(i = 0; i<0x1FFFFFE; i++){
	p = realloc(p, 6);
	p = realloc(p, 5);
	/*p = new char[6];
	delete[] p;
	p = new char[5];
	delete[] p;*/
	/*p = malloc(6);
	free(p);
	p = malloc(5);
	free(p);*/

}

printf("time: %ims\n", (clock() - time)/(CLOCKS_PER_SEC/1000));

}

next_time ★★★★★
() автор топика

почему в С98 и С++ realloc() пытается расширить текущий блок, и лишь в случае неудачи выделяет память на новом месте а в С99 — сразу выделяет память на новом месте?

AFAIK это проблема реализации. Разве нет? Может подскажешь точную ссылку на параграф в стандарте?

PS: лично я предпочитаю не использовать realloc.

emulek
()
Ответ на: комментарий от next_time

из справочника Герберта Шилдта

ЩИТО? Какого года???

emulek
()
Ответ на: комментарий от exception13
i++ + ++i + i++ + ++i

вполне себе неоднозначно.

дык тут полно точек следования, порядок которых не определён. А в примере с return ++i; точка следования одна.

Так кто же такое в здравом уме в продакшен коде напишет?

у меня для тебя плохие новости...

emulek
()
Ответ на: комментарий от next_time

Ну и что ты этим забенчил? В этом(этот случай какбэ вообще не имеет смысла, но предположим, что оно растёт у тебя по 10) случае просто юзается malloc(100500) и реалок нахрен не нужен.

anonymous
()
Ответ на: комментарий от AptGet

Похоже все сложнее, в стандарте есть дыра для поддержки функций в стиле K&R и gcc считает определения функций без параметров именно такими.

это для совместимости со старым говнокодом.

emulek
()
Ответ на: комментарий от next_time

Вообще кому сейчас нужен реалок я не знаю - выкинь его и забудь про него.

скорость

ты в этом ТОЧНО УВЕРЕН?

emulek
()
Ответ на: комментарий от next_time

по моим тестам реаллок быстрее, чем маллок + фри в 1,69 раза

дай тесты, и я скажу, ЧТДНТ.

emulek
()
Ответ на: комментарий от AptGet

это для совместимости со старым говнокодом.

dr. Obvious :)

некоторые этого увы — не понимают.

emulek
()
Ответ на: комментарий от anonymous

Ну и что ты этим забенчил?

фэйспалм

этот случай какбэ вообще не имеет смысла

по секрету расскажу: любой тестовый код не имеет иного практического применения, кроме как в тестах

просто юзается malloc(100500)

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

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

ну доказательство в том, что на самом деле glibc выделяет не 5 или 6 байт, а скажем 16. И когда ты делаешь realloc, у тебя просто размер этой области меняется с 5и на 6 и наоборот. Т.е. твой «тест» равносилен чему-то подобному:

void realloc1(size_t x)
{
  static int y;
  y = x;
}

int main()
{
  int j;
  for(j = 0; j < 100500; j++)
    realloc1(5), realloc1(6);
  return 0;
}

ну если не веришь, то посмотри в отладчике. Я на 146% уверен, что у тебя будет именно так.

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

И когда ты делаешь realloc, у тебя просто размер этой области меняется с 5и на 6 и наоборот

кстати, это должна делать ОС. в этом весь смысл реаллока

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

где доказательство?

доктор прав, такие маленькие области аллокатор glibc выделяет из пула и не возвращает.

просто посмотри strace'ом

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

не, не так: оптимизация-то отключена

нет, так. Я как раз про случай без оптимизации говорил. Потому что код realloc засунут внутрь glibc, и на него никакая оптимизация ессно не действует.

emulek
()
Ответ на: комментарий от next_time

кстати, это должна делать ОС. в этом весь смысл реаллока

кстати ОС не умеет выделять 5 байтов. И 6 тоже. Моя только 4096 умеет.

emulek
()
Ответ на: комментарий от AptGet

glibc — GNU C Library (GNU библиотека). Glibc является библиотекой Си, которая обеспечивает системные вызовы и основные функции

хотя, если учесть, что ядро само на сях, ответ на вопрос зависит от точки зрения

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

смысл реаллока

на самом деле, malloc(3) запрашивает у системы память, не менее 4096 байтов(1 страница в x86). Если нужно 5 или 6, то malloc(3), распиливает 4096 на куски, но не меньше 16 байт. Эти куски и отдаёт приложению как области «в 5 байтов». На самом деле, ничего страшного не случится, если в массив из 5и байт записать 6й(конечно не нужно такой быдлокод юзать IRL!!! Это только сейчас и только в x86!!!)

Т.е. если ты делаешь realloc 5=>6, то не происходит ровным счётом ничего. Если делаешь 5=>25, то glibc в пределах этой страницы обычно реаллоцирует, и адрес области не меняется. Т.е. блок просто расширяется, скажем 16=>32. Естественно, это возможно не всегда. Если делаешь 5=>9001, то данный механизм отключается, и выделяется три страницы(12288), из которых ты получаешь адрес начала первой страницы.

Т.о. в malloc(3) имеется два аллокатора, один для мелких кусочков <<4096, другой для более крупных. А твой «тест» вообще ничто «тестирует».

emulek
()
Ответ на: комментарий от next_time

вы начинаете догадываться зачем нужен реаллок и почему он может быть быстрее

быстрее ЧЕГО?

emulek
()
Ответ на: комментарий от Moonysh

Эм... У вас старый KnR. Во втором издании везде int func(void);

коммент не про книжку, а про объявления функций в допотопном стиле до стандартизации. Этот стандарт де-факто называют «K&R C»

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

а чем плохо такое поведение?

ничем, это оптимизация

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

а чем плохо такое поведение?

ничем не плохо. Было-бы лучше, давно бы поменяли. Вышеописанный способ самый лучший в сферически-вакуумном случае. А если тебе не нравится, сделай свой СБИШ.

emulek
()
Ответ на: комментарий от AptGet

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

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

значит, realloc эффективней: позволяет обходиться без (ре)аллокаций, там, где не может обойтись маллок+фри

угу. Разве это тебе не очевидно? Вот только откуда ты этот бред выкопал:

в С99 — сразу выделяет память на новом месте

Что-то не верится, что Шилдт такою чушь писал. Может это ГСМ-переводчик?

А смысл realloc'а как раз в этом и состоит, что-бы расширить память, если есть такая возможность(и нет желания велосипедить своё).

emulek
()
Ответ на: комментарий от next_time

Ты мне ответь - ты реально идиот? Ты понимаешь, что твой тест мериет «реалокацию» в том случае, когда после того куска, который ты реалоцируешь НЕ ВЫЗЫВАЛСЯ МАЛЛОК.

for(i = 0; i<0x1FFFFFE; i++){
	p = realloc(p, 6);
	p = realloc(p, 5);

Это равнозначно:

p = malloc(6);//работает, если ты догадался, на порядки быстрее.

Если ты напишешь более реальный юзкейс(у идиотов, конечно же):

for(i = 0; i<0x1FFFFFE; i++){
	p = realloc(p, i);

Это равнозначно:

p = malloc(0x1FFFFFE);//работает, если ты догадался, на порядки быстрее.

Если ты не совсем тотальный идиот ты поймёшь, почему ты несёшь херню, если же нет - мне тебя жаль.

Реалок имеет смысл только в таком юзкейсе:

for(i = 0; i<0x1FFFFFE; i++){
	p = realloc(p, i);
        ptr = malloc(10);
}

В это же случае реалок будет работать так же, как малокафри.

anonymous
()
Ответ на: комментарий от next_time

Ты мне ответь - ты реально идиот? Ты понимаешь, что твой тест мериет «реалокацию» в том случае, когда после того куска, который ты реалоцируешь НЕ ВЫЗЫВАЛСЯ МАЛЛОК.

for(i = 0; i<0x1FFFFFE; i++){
	p = realloc(p, 6);
	p = realloc(p, 5);

Это равнозначно:

p = malloc(6);//работает, если ты догадался, на порядки быстрее.

Если ты напишешь более реальный юзкейс(у идиотов, конечно же):

for(i = 0; i<0x1FFFFFE; i++){
	p = realloc(p, i);

Это равнозначно:

p = malloc(0x1FFFFFE);//работает, если ты догадался, на порядки быстрее.

Если ты не совсем тотальный идиот ты поймёшь, почему ты несёшь херню, если же нет - мне тебя жаль.

Реалок имеет смысл только в таком юзкейсе:

for(i = 0; i<0x1FFFFFE; i++){
	p = realloc(p, i);
        ptr = malloc(10);
}

В это же случае реалок будет работать так же, как малокафри.

anonymous
()
Ответ на: комментарий от emulek

Что-то не верится, что Шилдт такою чушь писал. Может это ГСМ-переводчик?

А смысл realloc'а как раз в этом и состоит, что-бы расширить память, если есть такая возможность(и нет желания велосипедить своё).

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

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