我在C中编写虚拟内存模拟器,在linux上编译,我得到了一些相当奇怪的东西。它接收一个文件IO,我将其放入int * plist。
我打印过这个" plist"数组,它出来了 0 100 1 200 2 400 3 300 等
问题是看起来malloc或其他东西正在随意改变plist [3]为0.它似乎不应该是那样的,但我在每一行都写了一个印刷语句代码打印plist [3]和
tables[i].valid = (char*) xmalloc(num_pages * sizeof(char));
是它改变的地方。 plist [3] = 300之前的行,0之后的行。并且它只在i = 2时执行此操作。循环的前3轮运行正常,在第3轮,它更改第4轮的值。我不知道为什么,malloc将改变值的意义没有多大意义一个完全不相关的数组 - 我是否有可能超过一些空间限制,即使我使用堆基本上都是什么?如果我这样做,它会改变随机数组中的值吗?
for(i = 0; i < 4; i++){
num_pages = plist[i] / P1;
tables[i].page_num = (char**) xmalloc(num_pages * sizeof(char*));
tables[i].valid = (char*) xmalloc(num_pages * sizeof(char));
//initialize page numbers and valid bits
for(j = 0; j < 10; j++){
tables[i].page_num[j] = (char*) xmalloc(16*sizeof(char));
tmp = itoa(i, tmp);
strcat(tables[i].page_num[j], tmp);
strcat(tables[i].page_num[j], "p");
tmp = itoa(j, tmp);
strcat(tables[i].page_num[j], tmp);
tables[i].valid[j] = 0;
}
}
这里是表格的结构:
typedef struct s_page_table
{
char** page_num;
char* valid;
} t_page_table;
这是xmalloc(它只是一个让它更容易的包装器):
void* xmalloc(int s)
{
void* p;
p = malloc(s);
if (p == NULL)
{
printf("Virtual Memory Exhausted");
exit(1);
}
return p;
}
编辑:如果我取出引用表[i] .valid的两行,则问题不存在。 plist [3]保持不变。 num_pages总是&gt; = 10.我将j设置为0到10只是为了减少输出以进行调试。
编辑2:如果我将char *中的有效值更改为int *它不起作用。如果我将其更改为int,则确实如此。
答案 0 :(得分:6)
有几种可能性,包括(但不限于):
tables[i]
超出范围; plist
包含一个悬空指针(即它已被取消分配); plist
尚未初始化; plist
没有您想象的那么大,即plist[3]
超出范围。如果您无法通过查看代码来解决问题,valgrind
就是您的朋友。
答案 1 :(得分:0)
行。所以我相信在初始化所有内容之前,问题就是在玩字符串。我并不完全确定原因,也许其他人可以详细说明,但是当我封装JUST初始化它自己的函数时,就像只执行mallocs,然后分别创建字符串后,plist变量不受影响。
对于那些感兴趣的人,封装的函数看起来像这样:
t_page_table* table_builder(int* p, int x, int num_tables)
{
t_page_table* ret = xmalloc(num_tables * sizeof(*ret));
int i, tmp, j;
for(i = 0; i < num_tables; i++){
tmp = (p[i]/x);
ret[i].page_num = xmalloc(tmp * sizeof(char*));
ret[i].valid = xmalloc(tmp * sizeof(char));
for(j = 0; j < tmp; j++){
ret[i].page_num[j] = xmalloc(16 * sizeof(char));
ret[i].valid = 0;
}
}
return ret;
}