powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Поймать факт перезаписи
23 сообщений из 123, страница 5 из 5
Поймать факт перезаписи
    #38079765
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumix, как только ты перейдешь на другой (высокоуровнеый) ЯП то забудешь свои мучения
как страшный сон. Нет правда. Тебе не нужен С++. У тебя от него зуд в одном месте
и болезни сердца и почек. И те проблемы с которыми ты воюешь они в продуктиве
не нужны. С ними просто никто не воюет. Меняют быстро постановку и пишут
боевой код. Никто new не перегружает!
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38079804
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonкак только ты перейдешь на другой (высокоуровнеый) ЯП то забудешь свои мучения
Ага, на хаскель надо переходить. Ну, так чтоб сразу в морг
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38079834
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я имел в виду Lua.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38079898
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyАга, на хаскель надо переходить. Ну, так чтоб сразу в морг

ну за 10-15 лет может как-то просветление наступит))) это просто в качестве сверхамбициозной мечты...
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38079920
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonLumix, как только ты перейдешь на другой (высокоуровнеый) ЯП то забудешь свои мучения
как страшный сон. Нет правда.

В нашей команде все знают пхп и яваскрипт, поэтому мы отлично знаем что такое работать без учета памяти. Более того, именно благодаря наличию меня в команде, все работают на с++ тоже не трогая вопросы памяти вообще. Это одна из моих ролей в команде.

Мы никогда не будем работать на луа. Это ошибочное решение с точки зрения рынка. Может если нас когда-нибудь занесет в геймдев, то может быть что-то и будем на нем черкать как дополнение к основному двигателю.

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


maytonТебе не нужен С++.

Нужен, нужен. )))

maytonУ тебя от него зуд в одном месте и болезни сердца и почек.

Нет у меня от него никакого зуда. Обычная рабочая нагрузка. Мало чем отличается от банальной отладки.

maytonИ те проблемы с которыми ты воюешь они в продуктиве не нужны. С ними просто никто не воюет.

Разумеется они не нужны, потому что кто-то эти проблемы однажды решил и все спрятал под капот, сдав в продакшен понятный и комфортный интерфейс.

mayton Меняют быстро постановку и пишут боевой код. Никто new не перегружает!

В бою new вообще нет. Это все спрятано под капот. Да и в обсуждаемых темах в итоге перегрузка new не потребовалась...
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38087523
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ответ на самый верхний пост -- можно, это делает либа под названием boehm gc

На днях я ее ковырял, было интересно как же она работает. Оказалось - просто. Она анализирует стек. Во всех архитектурах в стек пушается только числа фиксированной ширины, на i386 это 4байта, на 64 архитектуре 8... В стеке хранятся адреса возвратов и локальные переменные. И если локальная переменная - указатель, то можно посмотреть куда он указывает, а если есть список ранее выделеный участков памяти, то можно просмотреть есть ли в стеке указатель на этот участок.
вот так она и работает.

Ну и плюс куча извращений и костылей по получаения адреса стека одного потока из другого.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38087563
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хм... если идти по ссылкам от страницы этого boehm gc то можно найти интересные статьи
и ссылки на книги

http://www.memorymanagement.org/
http://www.iecc.com/gclist/GC-faq.html
http://www.cs.kent.ac.uk/people/staff/rej/gcbook/gcbook.html
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38087591
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chabapok,

А какой костыль решает такое?
Код: plaintext
1.
2.
3.
4.
5.
// swap
register tmp = ptr_a;
ptr_a = ptr_b;
// вот в этот момент нигде в памяти нет указателя ptr_a, но он по прежнему используется
ptr_b = tmp;
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38087597
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да.. сомнительно как-то. В Java декремент счётчика ссылок происходит
при потере scope. Это логично. Это надёжно. Вышел из скоупа - значит
референс потерял -1. Как можно анализируя стек (множество стеков!)
принять решение о том что объект можно удалять? Мистика.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38087608
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

Да проблема поиска по стекам ничем от кучи не отличается (на стеке даже проще, т.к. он однопоточный).
Но любой самый захудалый компилятор использует регистры для временных переменных.
Интересно как это решается в boehm.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38088000
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это вы меня спрашиваете??? Это я вас хочу спросить.

но если вам интересно мое мнение -- очевидно, программист должен понимать как работает эта либа, и пользоваться ею правильно. Вот вы, например, моментально поняли, я втыкал в нее полдня... В контексте вашего вопроса это означает - так как вы предложили, делать не надо. В плюсах много вещей, которые сделать можно, но не следует. Сама эта либа, насколько я понимаю, появилась раньше языков с mark&swep, обвинять ее том, что ее предерали с оных было бы глупо, однако сегодня она выглядит именно так.

Мне кстати удавалось ее обмануть без регистров. Она, помимо стека, анализирует (по всей видимости, рекурсиво) указатели, которые там хранятся. То есть если заалоцировать указатель:

int **p = (int **) GC_MALLOC(sizeof(int *));

и потом заалоцировать еще блок памяти, присвоив его этому указателю

(*p) = (int *)GC_MALLOC(50);

то либа "понимает" что эти 50 байт удалять не надо, хотя указатель на эту память хранится не в стеке.

но если мы заалоцируем массив и попытаемся его использовать:

int **p = (int **) GC_MALLOC( 10*sizeof(int *) );
p[5] = (int *) GC_MALLOC( 50 );

То либа "не видит" все, что дальше p[0].


mayton В Java декремент счётчика ссылок происходит при потере scope. Это логично. Это надёжно. Вышел из скоупа - значит референс потерял -1
Тут корректней было бы говорить о конкретном GC конкретной jvm. Только в оракловкой jvm их вроде 3 штуки разных. В проекте cacaovm их две, одна из которых - boehm. gcj тоже на boehm базируется. К тому же, даже если в яве подсчет ссылок есть, он служит для оптимизации, потому что бывают еще и циклические ссылки, и там подсчет бессилен.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38088022
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Off
chabapok, ты вырос в моих глазах. Особенно если сравнить твои
посты которые ты писал раньше. Будто человека подменили.
Рработяга...
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38088034
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
насчет того, что компилятор может самовольно сделать так, как вы пишите, засунув самовольно указатель - в регистр. gcc так не делает, по крайней мере с ключиком -O2
Но если с какими-то ключиками он будет так делать, то тогда надо будет использовать модификатор volatile там, где он нужен. Однако, насколько знаю, самовольно регистры он никогда не использует по той причине, что даже в однопоточной программе это может приводить к трудноуловимым ошибкам.

Если у нас есть указатель int* x; то нет никакой гарантии, что в программе нету int **y, который в какой-то момент времени начнет указывать на x. И если компилятор самовольно засунет x в регистр, то это будет совсем не то, что хотелось программисту, поэтому компилятор так не делает (возможно, ключик у него все же есть какой-то). поэтому, если такая оптимизация руками не включена, то можно не опасаться, ну а если эту оптимизацию включили - ссзб, ибо она даже по документации dangerous.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38088118
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chabapokнасчет того, что компилятор может самовольно сделать так, как вы пишите, засунув самовольно указатель - в регистр. gcc так не делает, по крайней мере с ключиком -O2
Но если с какими-то ключиками он будет так делать, то тогда надо будет использовать модификатор volatile там, где он нужен. Однако, насколько знаю, самовольно регистры он никогда не использует по той причине, что даже в однопоточной программе это может приводить к трудноуловимым ошибкам.
Что значит не делает?
Еще как делает. Ведь на большинстве платформ невозможно скопировать память-память без промежуточного регистра.
Хоть volatile хоть не volatile.

Ну и пример кода генерируемого -О2
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
int a = 1;
int b = 2;
int* volatile pa = &a;
int* volatile pb = &b;

int main()
{
    int* tmp = pa;
    pa = pb;
    pb = tmp;
    return *pa - *pb;
}



Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
    movq    pa(%rip), %rax
    movq    pb(%rip), %rdx
    movq    %rdx, pa(%rip)
    // вот здесь прежнее значение pa хранится только в регистре RAX
    movq    %rax, pb(%rip)
    movq    pa(%rip), %rax
    movq    pb(%rip), %rdx
    movl    (%rax), %eax
    subl    (%rdx), %eax
 
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38088232
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хм, проверил - действительно, потенциальная проблема имеет место.

Я думаю, этот неочевидная то ли фича то ли баг лежит на совести программиста. Странно, но по этой проблеме навскидку вообще ничего не нагугливается.

Волатильной в этом примере должна быть tmp. Делаем:

int* volatile tmp = pa;

и тогда получаем:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
	movq	pa(%rip), %rax
	movq	%rax, -8(%rsp)
	movq	pb(%rip), %rax
	movq	%rax, pa(%rip)
	movq	-8(%rsp), %rax
	movq	%rax, pb(%rip)
	movq	pa(%rip), %rax
	movq	pb(%rip), %rdx
	movl	(%rax), %eax
	subl	(%rdx), %eax
	ret



х86 ассемблер не мой конек, но похоже, теперь все ок.

Однако этот "баг", если делать без volatile, проявится только в многопоточной программе.

Еще одна особенность работы gcc в том, что он удаляет локальные переменные не при выходе из области видимости, а сразу когда она больше не нужна. Если экспериентировать с детектором утечек памяти который идет в составе boehm, то это очень хорошо видно.

получается, что boehm убирает одни проблемы, но зато вносит другие. И так и знал, что подвох обязательно будет. :((
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38088280
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chabapok,

А другая ситуация.
Если указатель указывает в середину массива, то ловится ли такое?
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38088320
sherzod_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chabapok,

насколько я понял либа не предназначена для прямого использования в программах на С и С++. Скорее для встраивания в VM языки, используя прослойку C/C++. Да и невозможно это, использовать ее прямо, принимая во внимание ограничения которые либа неизбежно должна накладывать на операции с указателями, которые далеко не ограничены регистровыми переменными, указателями на указатели, упаковыванием адреса в целое, косвенной адресацией, арифметикой, наличием указателей на функции, на функции-члены, полиморфизмом, кастами и тд и тп. скоро конец света, перечислить все не успеется, лучше за оставшееся время почитать кучу полезной инфы на сайте проекта, за что вам спасибо :).
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38088336
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Когда я пробовал, вроде ловилось, но если захочу так делать - еще раз это хорошенько протестирую.

То есть, если мы потеряем указатель на начало блока данных, но у нас будет указатель на его середину - этот блок все равно не будет освобожден.

Еще, похоже что, либа хранит в своем хипе контрольные суммы свободных блоков. Не знаю хорошо это или плохо, не знаю отключаемо ли это. Если мы где-то вылезли за пределы отведенной нам памяти и сделали туда запись, то когда-нибудь при очередном выделении памяти, этот gc находит испорченый блок и предупреждает нас. Там с либой этой идут тесты для нее, и в вних есть тест на такой функционал.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38088415
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sherzod_,

1. указатели на указатели либа ловит, но с ограничениями (см 13665184 где я описал этот случай), на то он mark&sweep.

2. Регистровые указатели вообще сомневаюсь что можно поймать, поэтому тут надо быть осторожным

3. упаковыванием адреса в целое само по себе не есть проблемой, потому что:
- адрес как правило все равно хранится в стеке
- если адрес уже перестанет хранится, а останется само целое, то его представление побайтово равно указателю и с точки зренния gc им будет являтся, поэтому пока это целое будет существовать в стеке или в хипе (с ограничениями п.1)- память не будет освобождена

4. косвенной адресацией, арифметикой -- не знаю что есть косвенная адресация, а арифметика сама по себе, как мы выяснили, не должна портить указатели, если происходит над волатильными переменными

5. наличием указателей на функции, на функции-члены, полиморфизмом, кастами
Для плюсов там есть плюсовый аллокатор.

Что же касается указателя на функцию, то функции не хранятся в хипе. GC смотрит куда указатель указывает -- не в хип. И это все, что ему надо. Если он встретил что-то, что указывает не в его хип -- это либо чужой указатель, либо вообще не указатель, его трогать не надо и не надо никак обрабатывать. Точно так же адреса возврата gc не будет никак обрабатывать, потому что они не указывают на его хип.

При этом, конечно, если побайтовое представление нескольких переменных нечаянно начнет "указывать" на хип - gc этот блок не высвободит. Поэтому, в большой программе неизбежен некоторый оверхед.

что-там будет с указателями на фукнцию-член обьекта - точно сказать не могу, но по идее должно работать, потому что указатель на сам обьект gc должен подхватить и корректно обработать.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38088490
sherzod_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chabapok,

Это просто высший класс! Давно не было такого четкого конкретного, без отвлечений, полного предметного ответа :). Согласен с каждым пунктом. За исключением того, что все же эту библиотеку вряд ли можно с разумными затратами на написание кода использовать прямо в программах на С и С++.

Кстати думаю вы все же ответили на вопрос ТС о возможности отслеживания изменения указателя, но цена не та и переносимость тоже.

И все же есть некоторые малозначимые поправки, упаковка в целое не обязана быть представлением адреса (вспомните про знаковые). Косвенная адресация и арифметика, это может быть все что угодно, что хранит адрес в разобранном виде и однажды собирает его, например простой случай, упомянутый Анатолием, хранения указателя на середину массива (потом можно вычислить и начало), насколько я понял этот случай ловится вычислением входимости в диапазон (но тогда возникают серьезные претензии к скорости, будет больше константы, по крайней мере логарифм точно, хотя что ж, это сборка мусора).

Если учитывать все ограничения от языка останется ни на что не годный обрубок. Ну может для чего-то вроде локальных std::vector< class T , gc_allocator<class T> > и подойдет, но уж явно не для полного избавления программы от ручного управления памятью. Ну что спорить-то :), либа явно не для ручного кода.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38088503
sherzod_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sherzod_std::vector< class T , gc_allocator<class T> > Здесь конечно стормозил, имелся в виду какой-нибудь пользовательский контейнер вместо std::vector, в котором не нужно отслеживать освобождение памяти элементов.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38088584
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторЗа исключением того, что все же эту библиотеку вряд ли можно с разумными затратами на написание кода использовать прямо в программах на С и С++.

Ну это уже больше следствие личных предпочтений и неприязней. Я, например, вообще не понимаю зачем для крупных вещей сегодня пользовать плюсы если есть ява - это к вопросу о "разумности затрат".

Насчет цены и переносимости. Как оно работает с большим хипом и большим количеством обьектов - я не знаю. Насчет переносимости -- этот gc портрован на много разных архитектур. Если заглянуть в его configure, там даже амига есть, есть упоминание архитектур в которых стек растет вверх а не вниз...

я с этим gc познакомился чуть ближе, когда пытался откомпилить cacaovm для qnx6 под i386. В портах оказалась только потоко-опасная версия. Пока мне не удалось это сделать, т.к. в qnx6 некорректно работает получение sp другого потока. Пока у меня не вышло с этим ничего сделать, и я на это забил, но думаю вернутся по свободе. Но это - исключение. Этот gc уже портирован на большинство известных архитектур большинства ОС. Если же надо что-то редкое, то все равно проблемы неизбежны. Не с одним - так с другим. Портабельность и С++ - вещи малосовместимые, к сожалению.

авторупаковка в целое не обязана быть представлением адреса (вспомните про знаковые).
Насколько я понял, вы считаете, что если мы упакуем аддрес в signed, то его побайтовое предстваление будет другим. На i386 и amd64 это не так. побайтовые представления совпадают. И я уверен, что на большинстве архитектур - тоже.

Ниже прога, сделаная "на скору руку", как доказательство.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
#include <stdio.h>
#include <memory.h>
#include <stdlib.h>

void printMem(void * addr){
    int i;
    unsigned char *cmem = (unsigned char *)addr;
    for(i=0; i<8; i++){
	printf("0x%x ", cmem[i] );
    }
    printf("\r\n");
}

int main(int argc, char ** argv){
    printf("sizeof(void*)=%lu\r\n", sizeof(void*) );
    printf("sizeof(long)=%lu\r\n", sizeof(long) );

    void * mem = malloc(300);
    long value = (long) mem;
    printMem(&mem);
    printMem(&value);

    mem= (void*) 0xffffffffffffffff; 
    value = (long) mem;
    printf("value=%li\r\n", value);

    printMem(&mem);
    printMem(&value);

}



На х64 вывод такой:

выводsizeof(void*)=8
sizeof(long)=8
0x10 0xa0 0xdd 0x1 0x0 0x0 0x0 0x0
0x10 0xa0 0xdd 0x1 0x0 0x0 0x0 0x0
value=-1
0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff


Если вы будете ее тестить на х32 то у вас sizeof(void*) будет равно 4, и тогда вам надо распечатывать и сравнивать по 4 байта а не по 8, и возможно вместо long подставить что-то четырехбайтовое (если long таковым не будет).

само по себе хранение адреса в разобраном виде не опасно, если при этом где-то хранится и собраный адрес. А вот если собранный адрес не хранится нигде - то да, это опасно, и так делать не следует, если используешь эту либу. Но тут надо отметить, что такие махинации с адресом сами по себе довольно низкоуровневы, опасны и не портабельны. Если бы прога без этой либы теряла адрес на начало блока, а потом его "находила" через разрозненные части - я бы сказал, что это говнокод. Поэтому лучше такое вообще не использовать, а если используешь - можно временно отключать сборку мусора, например.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38092747
poselort
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Круто
...
Рейтинг: 0 / 0
23 сообщений из 123, страница 5 из 5
Форумы / C++ [игнор отключен] [закрыт для гостей] / Поймать факт перезаписи
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]