【问题标题】:C DMA - Using brackets with malloced memoryC DMA - 使用带有 malloced 内存的括号
【发布时间】:2012-11-10 00:50:15
【问题描述】:

我已经有一段时间没有写 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; } }

【问题讨论】:

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


    【解决方案1】:

    在我看来SA_cache::sets 的类型应该是LRU* 而不是LRU**。正如 Jamey 所指出的,否则您在此处发布的内容将无法完全编译。此答案的其余部分假定类型为LRU*

    当你写作时:

    cur_lru = cache->sets[i];
    

    cur_lrucache-&gt;setsith 元素处获取,在您的情况下为零(可能是因为您的进程只是第一次看到此内存) .

    如果要使用数组下标,需要使用address-of操作符(&amp;):

    cur_lru = &cache->sets[i];
    

    cur_lru 然后获取 cache->sets 的 ith 元素的 地址。这在功能上与您发布的指针算法相同。

    【讨论】:

      【解决方案2】:

      由于cache-&gt;sets的类型是LRU **,所以cache-&gt;sets + i的类型也是LRU **。当您将结果分配给LRU *cur_lru 时,我预计您会收到编译器警告。 (您是否在未启用警告的情况下进行构建?)

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


      编辑:仔细阅读后,我发现您理解下标应该是正确的,并且您报告说代码只有在您引入这种类型错误时才有效。我坚持上述观点,事实上 GCC 报告“警告:来自不兼容指针类型的赋值”,即使没有 -Wall

      我可以在这段代码中找到的唯一另一个问题是,当您 mallocsets 数组时,您将每个元素的大小设置为 sizeof(LRU),而不是 sizeof(LRU *)。但是,几乎可以肯定,无论您在哪个平台上,都会使 LRU 结构大于指向 LRU 的指针,因此这不能解释您所看到的症状。

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

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

      【讨论】:

        猜你喜欢
        • 2021-09-22
        • 2014-11-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-30
        • 1970-01-01
        • 1970-01-01
        • 2011-07-01
        相关资源
        最近更新 更多