LINUX.ORG.RU

Связанные переменные

 ,


0

1

Ищу некий аналог absolute из delphi в си.

Ситуация: есть динмассив, построенный с помощью realloc. В нем хранятся структуры с полями. Чтобы добраться до какого-либо поля идет поиск по полю «ключ». Это занимает достаточно много времени (по крайней мере сейчас). Мне нужно очень часто общаться с одним из полей одного из элементов массива. При это мне известен его «ключ» и то, что он существует. Я хочу завести некую переменную, которая будет иметь тот же адрес, что и значения поля искомого элемента. Причем, мне нужно, чтобы была двусторонняя связь между переменными.

Аналог на delphi:

//Global
Var
  Purum : Integer;
  Murum : Integer absolute Purum;

Begin
 Purum := 5;
 WriteLn(Purum); // 5
 WriteLn(Murum); // 5
 Murum := 4;
 WriteLn(Purum); // 4
End.

Достаточно редкий трюк, его стараются мало использовать из-за опасности отстрелить себе ногу из ядерного ракетомета. Но тем не менее мне нужно его применить сейчас в Си.

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

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

Знаю. Хочу пример, ибо туплю, как мне правильно прицепиться к переменной.

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

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

Велосипед вашего покорного слуги: запись, поиск в индексах.

Eddy_Em ☆☆☆☆☆
()

А что мешает либо (если новый realloc не грозит) запомнить найденный адрес в отдельном указателе int*, либо (если realloc грозит, но смещение не изменится) хранить смещение. Получим что-то в стиле:

int *MurumCurrent = findKey(PurumPointer, «myKey»); /* Если нет проблем с выравниванием, то просто MurumCurrent-PurumPointer и используем как индекс массива */ int diff = ((char*)MurumCurrent - (char*)PurumPointer);

Обращение через PurumPointer (после очередного realloc): *(int*)((char*)PurumPointer + diff) = 5;

Можно оформить как макро.

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

Массив по сути - помойка пользователя. Но при этом я храню там пару служебных элементов.

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

Лучше все-так делать так, как показал qnikst. Хранить указатель на поле - не в стиле C.

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

Лол, и это мне говорит человек который не смог отличить кресты от не крестов. А потом придумал неведанный ЯП и согласился что то все таки не кресты.

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

вы сюда всеми яслями ходите, чтоле?

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

и почему у вашей аватарки такое лицо, будто она пукнула в нетрезвой компании?

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

Я так-то английского не знаю и читаю книги с гавнопереводом.

Я так-то сразу знал что это кресты, меня запутали.

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

nickionn ★☆
()

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

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

этот «небезопасный трюк»

Не этот. Указатели в delphi есть, и они используются. absolute - это более удобный вариант замаскированного указателя.

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

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

Eddy_Em ☆☆☆☆☆
()

Integer absolute Purum

Ну и костыль. Спасибо за новый аргумент для троллинга паскалистов.

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

Это все такие иногда удобней, чем обычный указатель. Например, когда какой-либо прибор посылает вам последовательность байт, а вам нужно эту последовательность расфасовать по переменным:

Type 
 TByteArray = Array[0..19] of Byte;
 TStructure = Record
    Address : Integer;
    Value     : Float;
    Point     : TPoint;
    Spectrum : Array[0..3] of Byte;

Function GetStructure(Data : TByteArray) : TStructure;
Var
  Structure : TStructure Absolute Data;
Begin
 Result := Structure;
End;

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

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

Структуры часто выравнены, так что подобные действия вполне могут наплодить ошибки. Думаю, всегда лучше делать нормальный демаршалинг.

А так это делается через memcpy.

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

Структуры часто выравнены, так что подобные действия вполне могут наплодить ошибки

man packed. Эта структура кратна 4-м байтам, на 32-х битной системе (компиляторе) отличий не будет.

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

Я не делаю такие вещи вообще, выше уже говорил.

Когда что-то зависит от того, что как выровнено, что чему кратно, какая архитектура, а иначе всё падает, это называется говнокод, имхо.

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

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

P.S.Справедливости ради, в c++ есть ссылки, которые ведут себя аналогично (почему, кстати, дельфины до сих пор на это не указали?), но с ними хоть нельзя отстрелить себе ногу как здесь:

Связанные переменные (комментарий)

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

ты что-то делаешь не так.

и, кажется, я даже знаю что именно:

Массив по сути - помойка пользователя. Но при этом я храню там пару служебных элементов.

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