Я пишу код здесь, чтобы попытаться скопировать виртуальную память в 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, который использует неправильный адрес при попытке доступа к нашему определенному каталогу страниц и таблицам страниц). Любой совет будет полезен. Спасибо.