указатель изменяется неожиданно, несмотря на то, что он не выходит из области видимости - PullRequest
0 голосов
/ 05 апреля 2020

Я пишу код здесь, чтобы попытаться скопировать виртуальную память в C. По какой-то причине указатель, который я создаю и поддерживаю в main, неожиданно меняется после передачи в функцию. Вот мой код в main

int main(){

    void * a = a_malloc(sizeof(int)*2);
    printf("1 a:%p\n",a);//1 a:0x1
    int x = 9;
    int y = 0;
    put_value(a,(void*)&x,sizeof(int));
    printf("2 a:%p\n",a);//2 a:0x1
    get_value(a,(void*)&y,sizeof(int));
    printf("3 a:%p\n",a);//3 a:0x8049050
    printf("y:%d\n",y);//y:9
    printf("4 a:%p\n",a);//4 a:0x8049050
    a_free(a,sizeof(int));

}

Код работает, как и ожидалось (y правильно держит значение 9), однако указатель «a» изменяется с исходного значения (0x1) на новое значение ( 0x8049050) после вызова get_value. Что интересно, хотя это то, что он не был изменен после put_value, что очень похоже на get_value, и ни один из них не должен быть в состоянии изменить указатель «a», который является локальным для main. Код для этих двух функций:

/* The function copies data pointed by "val" to physical
* memory pages using virtual address (va)
*/
void put_value(void *va, void *val, int size) {

   int pages = (int)(ceil((double)size/PGSIZE));
   int c=0;
   for(c=0;c<pages;c++){

       unsigned int addr = (unsigned int)va + (c*PGSIZE);
       void * pa = translate((void*)addr);
       addr = (unsigned int)val + (c*PGSIZE);
       memcpy(pa,(void*)addr,PGSIZE);
       c++;

   }
}


/*Given a virtual address, this function copies the contents of the page to val*/
void get_value(void *va, void *val, int size) {

   int pages = (int)(ceil((double)size/PGSIZE));
   int c=0;
   for(c=0;c<pages;c++){

       unsigned int addr = (unsigned int)va + (c*PGSIZE);
       void * pa = translate((void*)addr);
       addr = (unsigned int)val + (c*PGSIZE);
       memcpy((void*)addr,pa,PGSIZE);
       c++;

   }
}

PGSIZE - это значение, определенное в заголовке, которое в моем тестировании определено как 4096. translate здесь действительно не имеет значения, но на всякий случай

/*
The function takes a virtual address and page directories starting address and
performs translation to return the physical address
*/
void *translate(void *va) {

    translation =((page_directory[get_top_bits((unsigned)va)]).pagetable[get_mid_bits((unsigned)va)]).paddr;


    return translation;

}

Я прошел через код несколько раз, используя GDB, и я не могу найти точно, где 'a' сбрасывается, или даже как его сбрасывают. Поскольку он сбрасывается, вызов a_free segfaults (так как он вызывает translate, который использует неправильный адрес при попытке доступа к нашему определенному каталогу страниц и таблицам страниц). Любой совет будет полезен. Спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...