4

我正在实现一个函数,该函数通过调用deallocate_cache(void *ptr).

我手头任务的记忆结构如下:

 22 typedef struct slab {
 23         void *addr;
 24         int bm[((SLAB_SIZE/8)/(8*sizeof(int)))+1]; // bitmap
 25         struct slab *next;
 26 } slab;

 39 typedef struct {
 40         int alloc_unit;
 41         slab S;
 42 } cache;

 45 typedef struct { // structure for the entire memory
 46         cache C[9];
 47         region *R;
 48 } memory;

因此,我有一个memory M,其中包含缓存c[0]c[1]、 ...、c[8],而这些缓存又包含slabs. 当一个通过分配填满时,我通过字段slab分配另一个作为链表元素。slab *next

为了使我deallocate_cache(void *ptr)的工作正常,我必须首先找出是否ptr在缓存范围内,如果是,则在哪个缓存范围内。这是我到目前为止所拥有的:

 1.    // Check if ptr is in the range of (slab_addr, slab_size) for each slab in each cache
 2. int ci = 0, counter, coefficient, done, freeable;
 3. slab *look_ahead;
 4. for(; ci < 9; ci++){
 5.         void *max_addr = &M.C[ci].S + SLAB_SIZE; // The upper bound of the address range of the first slab
 6.         counter = 1;
 7.         look_ahead = &M.C[ci].S;
 8.         while(look_ahead->next != NULL){
 9.             if( ptr > look_ahead->addr && ptr > max_addr){ // Check ptr is greater than S.addr. If yes, it's a good bet it's in this cache.
10.                 look_ahead = look_ahead->next;
11.                 max_addr += SLAB_SIZE; // Now the upper bound of the address range of the following slab
12.                 counter++; // slab counter, 1-based counting
13.             }
14.             else {
15.                     done = 1;
16.                     break;
17.             }
18.         }
19.         if(done == 1) break;
20.
21. }

不幸的是,很明显,这并没有按预期工作。有什么方法可以使用这样的指针来比较地址,或者检查指针是否在给定的地址范围内?还是我必须简单地比较我知道分配给的最大范围内的每个地址?任何帮助深表感谢。

4

1 回答 1

3

首先,您不能在指向 的指针中添加任何内容或从中减去任何内容void

指针算法仅针对指向已知大小的事物的指针定义。void,与charorintchar*or不同struct slab,没有已知的大小。这是因为对指针进行加法或减法会使指针中的地址增加指针所指大小的倍数。

因此,如果您char* p;随后p = p + 1;sizeof(char)(即 1)添加到指针中的地址,但如果您long* p;随后p = p + 1;sizeof(long)(通常为 2、4 或 8)添加到指针中的地址。

然而奇怪的是,同样的限制适用于将指针与>, <, >=,进行比较<=。比较的指针必须指向相同的类型,不能是void.

我认为您需要使用指针char而不是指针void或将后者转换为前者才能进行指针运算。

另一个需要注意的重要事项是,如果这些指针不指向同一个数组或同一个对象(可以像结构一样聚合) ,那么您不能合法地将指针与>, <,进行比较。C 标准声明这相当于未定义的行为。>=<=

因此,如果您分别分配两个对象(作为单独对象的声明或作为单独调用malloc()或类似的),那么您不能合法地将指向这两个对象的指针与>, <, >=,进行比较<=

==但是!=可以做到。

此比较限制的一个常见解决方法是将指针转换为uintptr_t,这是一种保证能够保存指针的无符号整数类型,并对此整数类型执行常规算术运算,然后,如果需要,将其转换(转换)回指针类型。

当然,这只有在您的编译器有意义地定义指向整数的指针和整数到指针的转换并保证通过转换指向它们的指针获得的整数值是内存地址时才有效。

使用此信息更正您的代码。

于 2013-04-08T00:39:15.543 回答