我的问题与通过传递数组的地址将整数数组传递给函数有关。整数数组在函数外部正常运行,但不在内部。我写的大部分内容只是为了提供一些可能有用或可能没用的额外细节。要获得问题的真正要点,您可以跳到TL; DR在底部。
有两种结构: lineType是一个由两个整数值(有效和标记)
组成的结构typedef struct
{
int valid;
int tag;
} lineType;
setType是一个结构,由指向一组行的指针和一个指向整数分组的指针组成。
typedef struct
{
lineType * lines;
int * iruQueue;
}
我有一个指向称为缓存的setTypes分组的指针(对于任何熟悉计算机系统的人来说,此对象用于表示缓存系统。缓存有许多集合,每个集合都包含许多包含标记的行,指示该行是否包含有效信息的位,以及该行所保存的实际信息的字节偏移量。这不是我的主要问题所必需的,但我认为这可能会澄清我试图做的事情。 / p>
所以我们有setType * cache。
我创建了一个为缓存分配适当空间的函数,称为initCache。再次,不确定这些信息是否必要,但我想抛弃所有细节。
setType * initCache(int NoSets, int NoLines)
int i, j;
setType * cache;
//allocates the appropriate space for the sets
cache = malloc(sizeof(setType) * NoSets);
for(i = 0; i < NoSets; i++)
{
//allocates the space for the lines and the integer array
cache[i].lines = malloc(sizeof(lineType) * NoLines);
cache[i].iruQueue = malloc(sizeof(int) * NoLines);
}
//initializes all valid bits to 0 and the iruQueue entries to -1
for(i = 0; i < NoSets; i++)
for(j = 0; j < NoLines; j++)
{
cache[i].lines[j].valid = 0;
cache[i].iruQueue[j] = -1;
}
return cache;
}
所以这实际上是缓存构造函数。没有问题。我写了很多代码,但经过全面测试后它们都能正常运行。
更多背景:iruQueue整数数组用于跟踪集合中最近访问的行。例如:我有四行,数组初始化为int *,看起来像(-1,-1,-1,-1)。访问第0行。 (0,-1,-1,-1)。访问第1行。 (0,1,-1,-1)。访问第2行(0,1,2,-1)。再次访问第0行。 (1,2,0,-1)
这是我的问题:在某些时候我想将整数数组传递给一个将在缓存中修改它的函数。为此目的,我有两个函数,入队和出队。这是入队函数。
void enqueue(int ** iruQueue, int noLines, int lineNo)
{
int cached = 0;
int i;
for(i = 0; i < noLines; i++) {
if(*iruQueue[i] == -1 && cached == 0) {
*iruQueue[i] = lineNo;
cached = 1;
}
}
}
在上面的函数中,我传递一个指向我想要修改的特定iruQueue数组的指针,以及一组中的行数和刚才使用的行数。它搜索iruQueue,找到值为-1的第一个索引(表示索引未使用)并将其替换为行号。我将特定的iruQueue传递给这个函数。
cache(&(cache[setIndex].iruQueue), noLines, lineNo);
所以这就是我真正遇到问题的地方。我注意到它会在第一次入队调用时起作用,但在随后的队列/队列中无效。
在排队/出队之前打印这样的特定队列(NoSets是缓存阵列中setTypes的数量,NoLines是集合数组中的行数)
int i, j;
for(i = 0; i < NoSets; i++) {
for(j = 0; i < NoLines; j++)
printf("%d, ", cache[i].iruQueue[j])
}
产生以下内容:“-1,-1,-1,-1,”当有四行和一组时。在使用lineNo为0的一个入队之后,它产生“0,-1,-1,-1”。正常运作在那里结束。
我很好奇,所以在我的enqueue函数中,我添加了一些代码来在修改之前和之后打印iruQueue数组。
void enqueue(int ** iruQueue, int noLines, int lineNo)
{
int cached = 0;
int i;
//checks the iruQueue array prior to modification
printf("Before: \n");
for(i = 0; i < noLines; i++) {
printf("%d : %d\n", i, iruQueue[i]);
}
for(i = 0; i < noLines; i++) {
if(*iruQueue[i] == -1 && cached == 0) {
*iruQueue[i] = lineNo;
cached = 1;
}
}
//checks the iruQueue array after modification
printf("After: \n");
for(i = 0; i < noLines; i++) {
printf("%d: %d\n", i, iruQueue[i]);
}
}
这是我们从未修改的iruQueue数组开始时打印的内容(意味着所有值应为-1),行数为4,行号为0。
Before:
0 : -1
1 : 0
2 : -1
3 : 0
After:
0 : 0
1 : 0
2 : -1
3 : 0
似乎修改的iruQueue已经改变,因为每个适当的值之间存在零。如果我将打印功能更改为通过noLines * 2进行打印,则该模式将继续。那是我的问题。当iruQueue未传递给enqueue / dequeue函数并且我以相同的方式打印其内容时,它将正确打印,没有包含零的额外索引。为什么这样做会改变它,并且有什么办法可以解决它吗?
TL; DR
我通过将int数组的地址传递给函数(&amp;(cashe [setIndex] .iruQueue))将整数数组(int * iruQueue)传递给函数。它在函数外部运行,但是当传递给函数时,它会在每个正确的索引之间创建额外的索引,其值为0。我该如何解决这个问题?
如果需要更多代码/澄清,我很乐意提供。另外,如果我做错了这一切(写得太多或者说太多了)只是让我知道 - 虽然我在这个网站上阅读了很多东西来帮助解决我的问题,但我真的没有在这里发帖,所以我只是希望尽可能彻底。
谢谢!
答案 0 :(得分:1)
实际上,这里不需要你的双指针并使问题复杂化。您在访问时取消引用它,但在打印时不要取消它(这是错误的;我想知道为什么它不会崩溃或产生更多“随机”输出......)。只需将其缩小为单个指针:
void enqueue(int * iruQueue, int noLines, int lineNo)
{
int cached = 0;
int i;
for(i = 0; i < noLines; i++) {
if(iruQueue[i] == -1 && cached == 0) {
iruQueue[i] = lineNo;
cached = 1;
}
}
}
void foo()
{
enqueue(cache[setIndex].iruQueue, noLines, lineNo);
}