C DMA - 使用带有malloced内存的括号

时间:2012-11-10 00:50:16

标签: c malloc dynamic-memory-allocation square-bracket

我写了C已经有一段时间了,所以这个错误让我觉得我在失去理智。我正在编写一个程序来建模一个简单的缓存。不要担心细节。

问题是我初始化缓存时。在SA_cacheInit中的行:

cur_lru = cache->sets + i;//[i];

使用括号失败并且在GDB中检查时,即使i = 0,它也会给出一个空指针。但是如果我只使用普通指针算法,它就会起作用。我做错了什么?


typedef struct s_LRUnode {
  int tag;
  bool valid;
  bool dirty;
  struct s_LRUnode *next;
  struct s_LRUnode *prev;
} LRUnode;

typedef struct s_LRU { size_t size; LRUnode *head; LRUnode *tail; } LRU;

typedef struct s_SA_cache { size_t blocksize; size_t num_blocks; size_t set_size; LRU **sets; } SA_cache;

void cachesim_init(int blocksize, int cachesize, int ways) { cache = malloc(sizeof(SA_cache));

if ( cache != NULL ) { assert( powerOfTwo(cachesize) && powerOfTwo(blocksize) ); cache->num_blocks = cachesize / blocksize; cache->blocksize = blocksize; cache->set_size = ways; cache->sets = malloc(sizeof(LRU)*cache->num_blocks); //cache->num_blocks*ways); if (cache->sets == NULL) { printf(stderr, "Malloc failed in %s\n", func); } SA_cacheInit(cache, cache->num_blocks, ways); } else { fprintf(stderr, "Could not allocate memory for cache\n"); exit(-1); } }

void SA_cacheInit(SA_cache *cache, size_t num_blocks, size_t size) { int i; LRU *cur_lru;

for (i = 0; i < num_blocks; i++) { cur_lru = cache->sets + i;//[i]; cur_lru->size = size; cur_lru->head = NULL; cur_lru->tail = NULL; } }

2 个答案:

答案 0 :(得分:2)

在我看来SA_cache::sets应该有LRU*类型而不是LRU**。正如Jamey指出的那样,你在这里发布的内容不会干净利落地编译。本答案的其余部分假定类型为LRU*

当你写:

cur_lru = cache->sets[i];

cur_lru获取i的{​​{1}}元素的,在您的情况下为零(可能因为您的流程刚刚看到此记忆第一次。)

如果要使用数组下标,则需要使用address-of运算符(cache->sets):

&
然后

cur_lru = &cache->sets[i]; 获取缓存 - &gt;集的cur_lru元素的地址。这在功能上与您发布的指针算法完全相同。

答案 1 :(得分:1)

由于cache->sets的类型为LRU **,因此cache->sets + i的类型也为LRU **。当您将结果分配给LRU *cur_lru时,我希望您收到编译器警告。 (你是在没有启用警告的情况下建造的吗?)

来自不兼容指针类型的此分配意味着您正在写入sets数组中的指针,就像它们是LRU结构的字段一样。


编辑:仔细阅读后,我看到您明白下标应该是正确的,并且您报告的是代码仅在您引入此类型错误时才有效。我支持上述内容,实际上GCC报告“警告:从不兼容的指针类型中分配”,即使没有-Wall

我在此代码中可以找到的唯一其他问题是,当您malloc sets数组时,您将每个元素的大小设置为sizeof(LRU),而不是sizeof(LRU *)。但是,无论你使用什么平台,LRU结构都比指向LRU更大,所以这不应该解释你所看到的症状。

请注意,如果您使用优化(gcc -O2或类似)进行编译,那么gdb报告的信息可能会产生误导。当您引入类型错误时,您可能会阻止gcc优化初始化,并且可能是gdb报告您所期望的唯一原因。

我强烈建议您使用gcc -Wall进行编译并修复所有警告。然后,如果还没有解决问题,请在Valgrind下运行程序以捕获各种内存错误。