Почему адреса файлов, хранящихся на диске (vbox vm), различаются каждый раз, когда я просматриваю их?

Я знаю о ASLR, который каждый раз загружает программу в разные места памяти, однако я не уверен, почему это происходит в случае файлов, которые я сохранил на диске /dev/sda2 моей виртуальной машины Linux.

mp:projects-20:17:09-$ ./lseek_demo 
The end offset of file1 is 1268
The start  offset of file2 is 0
Diff between them is -1268
The mem address of file1 is 0x7ffce008e738
The mem address of file2 is 0x7ffce008e740


mp:projects-20:17:12-$ ./lseek_demo 
The end offset of file1 is 1268
The start  offset of file2 is 0
Diff between them is -1268
The mem address of file1 is 0x7fff9113e148
The mem address of file2 is 0x7fff9113e150

вот код, который я использую

#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <error.h>

void   offsets(const char* fname1,const char*  fname2)
{
        int fd0 = open(fname1, O_RDWR);
        int fd1 = open(fname2, O_RDWR);

        if (fd0 == -1 || fd1 == -1)
                perror("opne");

        off_t off_fd0 = lseek(fd0, -1, SEEK_END);
        off_t off_fd1 = lseek(fd1,0,SEEK_SET);


        close(fd0);
        close(fd1);

        printf ("The end offset of file1 is %ld\n The start  offset of file3 is %ld\n Diff between them is %ld\n",off_fd0, off_fd1,(off_fd1 - off_fd0));
        printf ("The mem address of file1 is %p\n The mem address of file2 is %p\n",&off_fd0,&off_fd1);
}

int main()
{
        offsets ("readme.txt","slack_space_calc.c");
        return 0;
}

Это составлено на ubuntu 6.8.0-38-generiC#38-Ubuntu

«Адрес памяти» вашего файла — это адрес локальной переменной в вашей функции.

Shawn 25.07.2024 16:53

Что такое «адрес файла, хранящегося на диске»? Вы печатаете адрес переменной-указателя в вашей программе. Это вообще не связано с файлом. Они хранятся в стеке, и ОС может назначить любой адрес вашей программе.

Gerhardh 25.07.2024 16:54

Думайте об операторе & как об указателе на оператор. Это означает, что, например, &off_fd0 — указатель на переменную off_fd0.

Some programmer dude 25.07.2024 16:55

Разница между смещениями двух разных файлов совершенно бесполезна и бессмысленна. Между ними нет никакой связи.

Shawn 25.07.2024 16:56

Вероятно, самым близким к адресу диска является индексный дескриптор. См. stat, если хотите это проверить.

Stephen Newell 25.07.2024 16:56

Смещение, которое вы получаете от lseek, — это количество байтов от начала файла до текущей позиции в файле, где следующая операция чтения или записи получит доступ к файлу. Начальное смещение всегда равно 0, а конечное смещение — это размер файла в байтах.

Bodo 25.07.2024 17:55

Начнем с того, что файлы не имеют адресов.

n. m. could be an AI 25.07.2024 18:45
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
7
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Этот код:

        off_t off_fd0 = lseek(fd0, -1, SEEK_END);
        off_t off_fd1 = lseek(fd1,0,SEEK_SET);

объявляет две локальные переменные целочисленного типа со знаком (некоторая неуказанная длина в битах) и устанавливает для них возвращаемые значения lseek(). Эти переменные принудительно сохраняются в стеке с помощью кода ниже; подробнее об этом чуть позже.

Выражение &off_fd0 возвращает указатель на переменную off_fd0, а не адрес «файла». Итак, когда вы печатаете его с помощью %p, вы печатаете адрес памяти этой переменной стека.

Интересное примечание. Если вы удалили этот оператор печати, есть большая вероятность, что компилятор оптимизирует одну или обе переменные. Т.е. он сохранит возвращаемые значения вызовов lseek() в регистрах ЦП. В этот момент переменные вообще не имеют адреса. (Это зависит от того, какой компилятор вы используете, целевой архитектуры ЦП и уровня оптимизации, выбранного для компиляции.) Наличие выражения &off_fd0 вынудило компилятор выделить хранилище стека для этой переменной, и в процессе этого ваш код был немного менее эффективно, чем могло бы быть.

Что касается того, почему адрес этой переменной меняется от одного запуска к другому. Было время, когда это было не так: каждый раз, когда вы запускали программу, стек находился в одном и том же месте. Добро пожаловать в ASLR — даже стек перемещается.

Наконец, как насчет адреса самого файла? Ну, у него нет адреса в памяти, но можно сказать, что номера дисковых блоков содержимого файла представляют собой «адрес» файла. Если вы посмотрите на них, вы обнаружите, что файлы не перемещаются; они практически остаются на одном и том же месте на диске, хотя даже это не является непреложным правилом. Если вы хотите узнать номера этих дисковых блоков, тогда удачи. Каждый тип файловой системы имеет свой собственный способ получения информации, а также RAID и NAS, и изучение всего этого выходит за рамки этого ответа.

Другие вопросы по теме