【问题标题】:GDB: "warning: Range for type <error type> has invalid bounds"GDB:“警告:类型 <错误类型> 的范围具有无效边界”
【发布时间】:2026-01-07 07:40:02
【问题描述】:

我有一个 C/GDB 编码问题让我抓狂。 (在 Linux 机器上编码,使用 GCC 作为我的编译器。)

我正在处理一项必须编写硬件缓存代码的任务,这基本上意味着我需要使用一个二维结构数组,我已将其 typedef 为结构cacheLine。以下是我对代码中数组的看法:

 [*] [*] [*] [*]    ...so here...  numSet = 4            (columns)
 [*] [*] [*] [*]                   numLines = 12         (total)
 [*] [*] [*] [*]                   numLinesPerSet = 3    (rows)

所以“numLines”实际上是cacheLine 结构的总数,而不是数组中的行数。 (我并不是说这会让人感到困惑,它与分配命名法有关。)

以下是我认为应该通过引用分配和传递数组的方式:

void initCache(int numSets, int numLines, cacheLine* (*cache)[numLines], int numLinesPerSet){
    int i, j;
    for(i=0; i<numSets; i++){
            for(j=0; j<numLinesPerSet; j++){
                    // Now allocate each struct one-by-one
                    cache[i][j] = (cacheLine*) malloc(sizeof(cacheLine));
                    if(cache[i][j] == NULL){
                            printf("Error: not enough memory to malloc() cache.\n");
                            exit(EXIT_FAILURE);
                    }
            }
    }
}

int main(){
    ...
    cacheLine* myCache[numSets][numLines];                  // declare
    initCache(numSets, numLines, myCache, numLinesPerSet);  // allocate
    ...
}

(是的,最后有一个类似的 freeCache() 函数,我在这里省略了。)

到目前为止,一切都编译并运行良好。当我使用 GDB 进入 initCache() 时,它看起来还不错:

Breakpoint 1, main (argc=2, argv=0x7fffffffe308) at c-sim.c:55
56              initCache(numSets, numLines, myCache, numLinesPerSet);
(gdb) step
initCache (numSets=4, numLines=12, cache=0x7fffffffdf28, numLinesPerSet=3) at c-sim2.h:122
122     void initCache(int numSets, int numLines, cacheLine* (*cache)[numLines], int numLinesPerSet){
(gdb)

到目前为止,一切都很好。对我来说,这就是事情的发展方向。稍后在代码中,我调用了另一个函数,它的签名与我的 initCache() 非常相似:

void cacheThisData(int numSets, int numLines, cacheLine* (*myCache)[numLines], int someData) {
    // do stuff with someData
}

int main(){
    ...
    cacheLine* myCache[numSets][numLines];                  // from
    initCache(numSets, numLines, myCache, numLinesPerSet);  // before...
    ...
    int someData;    //  holds data to-be-cached
    cacheThisData(numSets, numLines, myCache, someData);
    ...
}

当我使用 GDB 进入 cacheThisData() 函数时会发生以下情况:

Breakpoint 1, main (argc=2, argv=0x7fffffffe308) at c-sim.c:105
105                                     cacheThisData(numSets, numLines, myCache, someData);
(gdb) step
cacheThisData(numSets=4, numLines=12, warning: Range for type <error type> has invalid bounds 0..-72057594037927936
warning: Range for type <error type> has invalid bounds 0..-72057594037927936
myCache=warning: Range for type <error type> has invalid bounds 0..-72057594037927936
warning: Range for type <error type> has invalid bounds 0..-72057594037927936
warning: Range for type <error type> has invalid bounds 0..-72057594037927936
warning: Range for type <error type> has invalid bounds 0..-72057594037927936
warning: Range for type <error type> has invalid bounds 0..-72057594037927936
warning: Range for type <error type> has invalid bounds 0..-72057594037927936
warning: Range for type <error type> has invalid bounds 0..-72057594037927936
0x7fffffffdf28, data=1234) at c-sim3.h:145
145     void cacheThisData(int numSets, int numLines, cacheLine* (*myCache)[numLines], int someData) {
(gdb)

什么鬼???代码似乎仍然运行良好,但我担心 GDB 在这里闻到的任何问题都会再次困扰我。最好现在修复它。

我注意到如果我将cacheThisData() 的函数签名更改为只传递数组,GDB 不会介意:

void cacheThisData(int numSets, int numLines, cacheLine* (*myCache)[numLines]) {}

int main(){
    cacheThisData(numSets, numLines, myCache);   // GDB likes this
}

但是当我在cacheThisData() 的签名中的任何地方添加一个额外的参数时,我得到了上面的 GDB 警告,总是一样的。我将额外的参数放在cacheThisData() 的开头、中间或结尾都没有关系 - GDB 抱怨。

我不知道该怎么做。 GDB 似乎是在说我传入了尺寸不正确的myCache 数组???但是 numSets 和 numLines 不会改变。我也不会 realloc() 或类似的东西来改变数组的大小。数组不会在 initCache()cacheThisData() 函数之间改变大小,至少据我所知是这样。

有什么建议吗?有没有人遇到过这种情况?

谢谢, -皮特

【问题讨论】:

  • 您使用哪个 GCC、GDB 版本?你如何编译、调用GDB?
  • 你能用你展示给我们的最少代码重现这个吗?那就是删除所有...?
  • 对不起,我的程序很大。我故意想发布一个骨架版本来了解基本的想法。我现在知道这不是一个好帖子。

标签: c multidimensional-array gdb warnings pass-by-reference


【解决方案1】:

我从来没有找到这个问题的根源。但是,我的代码能够处理相当大的数据集并且还没有破坏,所以这就是一些东西。我要把这归结为生命的奥秘……然后继续前进。非常感谢所有停下来阅读这篇文章的人。

【讨论】:

    最近更新 更多