【问题标题】:Global Array of Structs, declare size in program and use globally without passing?结构体的全局数组,在程序中声明大小并在不通过的情况下全局使用?
【发布时间】:2019-04-28 09:41:22
【问题描述】:

仅出于上下文考虑,我将缓存模拟器制作为 C 项目。我需要声明一个struct的全局double数组,在程序中设置这个全局struct数组的大小,然后在项目中使用这个全局数组。

这里是我所拥有的缩短版:

// Declare globals
int mapping = 0;
int offset = 0;
int index = 0;

char* allocation;
char* writePolicy;

struct cache {
    int validBit;
    int dirtyBit;
    unsigned int tag;
    unsigned int nextToReplace;
    };

void analyzeParameters(char* line, int lineNum) {

switch(lineNum) {
        case 1:
            mapping = atoi(line);
        case 2:
            offset = atoi(line);
        case 3:
            index = atoi(line);
        case 4:
            allocation = malloc(4);
            strcpy(allocation, line);
        case 5:
            writePolicy = malloc(4);
            strcpy(writePolicy, line);
    }

}

setupCache() {
int numSets = 1 << index;

struct cache cache[mapping][numSets];

printf("Declared cache struct with size %d ", numSets);
printf("num of ways %d\n", mapping);

// initialize bits in cache to 0

int j;
int i;

for (j = 0; j < mapping; j++) { 
    for (i = 0; i < numSets; i++) {
        cache[j][i].validBit = 0;
        cache[j][i].dirtyBit = 0;
    }
}

}

void hitChecker() {

for (d = 0; d < mapping; d++) {
    if (cache[d][index].validBit == 1) {
        if (cache[d][index].tag == tag) { 
            //found a hit

            if (type == "r") {
            // hit with a read instruction.
            rhits++;


            }
            else if (type == "w") {
            // hit with a write instruction
            whits++;

            }
        }

        else {
        // tag in cache index is not equal to tag being checked

            if (type == "r") {
            // missed with a read instruction.
            rmisses++;

            }
            else if (type == "w") {
            // missed with a write instruction
            wmisses++;

            }
        }
    }
    else {
    //cache is not valid
    printf("Cache has not been validated");
    }
}

void main(int argc, char**argv) {

analyzeParameters(passInEachLineOfFile, this works not important);

setupCache();

hitChecker();

}

在我尝试使用缓存结构之前,这一直有效。我在全局声明它,在 setUpCache 中设置大小,然后在另一个方法中我想使用全局声明的双数组。有没有办法可以全局使用它,还是必须通过方法参数传递结构?

【问题讨论】:

  • passInEachLineOfFile 文件中的行有多长?
  • 对不起,我对此非常不清楚,我不想占用太多空间。它正在读取一个有 5 行的文件。第一行始终是缓存的映射,第二行始终是偏移量,第三行始终是索引,依此类推。我所做的是遍历文件中的每一行,以及代表我所在行的计数器。如果我在第一行,我将全局 int 映射设置为该值,依此类推。在我的测试场景中,第 1 行是 1,第 2 行是 5,第 3 行是 8。这些被传入并设置为全局整数
  • 这样不清楚是可以的。不检查 strcpy(writePolicy, line); 中的溢出是不行的。当您使用malloc(4) 分配内存时,您应该strlcpy(..., 4, line)cache 变量在void hitChecker() 函数范围内如何/在哪里声明?
  • 天哪... struct cache cache[mapping][numSets]; 被声明为本地的,因此不是全局的。一旦函数退出,它就不再存在了......
  • @PaulOgilvie(这是我给别人贴标签的方式吗?我是菜鸟)这很有意义哈哈。有没有办法让它成为全球性的,同时能够在全球范围内确定和声明大小?

标签: c arrays struct malloc parameter-passing


【解决方案1】:

如果你想使用cache作为全局变量,在全局范围内声明它,使用它之前。

struct cache {
    int validBit;
    int dirtyBit;
    unsigned int tag;
    unsigned int nextToReplace;
    };

struct cache cache[mapping][numSets];

如果可以避免的话,将变量放在全局范围内并不是一个好主意。

在这里,为了“封装”缓存功能,我建议在一个单独的文件中使用一个静态变量,所有缓存-相关函数,让它在“文件”范围内。由于mappingoffsetindex 是来自缓存函数外部的参数,请将它们作为参数传递。

// cache-lib.c

// Declare the struct in the c file, it's only needed here
struct cache {
        int validBit;
        int dirtyBit;
        unsigned int tag;
        unsigned int nextToReplace;
        };

static struct cache cache[mapping][numSets];

// Stores below variable here, in the "file" scope.
static mapping, offset, index;

// Below cache functions. Declare them an includable header.

/// setupCache() definition. Since it needs mapping, offset and index which
/// are retrieved from the outside, you can pass them as parameter.

void setupCache(int mapping, int offset, int index) {
  //// [...]
}

/// hitChecker. Maybe you need here to store extra variables
/// as "file-scope" ones like index and mapping
void hitChecker() {
  //// [...]
}

最后,您将在需要缓存库的任何地方使用的标头:

// cache-lib.h

void setupCache(int mapping, int offset, int index);
void hitChecker();

您也可以将其包含在您的 cache-lib.c 中,以免打扰与函数声明顺序相关的问题。

【讨论】:

  • mappingnumSets 不是常量,在编译时是未知的。
  • 哦,在我从我的方法中确定映射和 numSets 之前,我仍然可以全局声明 struct cache cache[mapping][numSets] 吗?
  • @JohnnyMopp,我的回答不完整,只是一个小例子。
  • 哦,我会稍微尝试一下。感谢您的回答!
  • @Amessihel 一个简单的愚蠢问题,但是当您提到“在包含的标头中声明它们(映射、偏移和索引)时,我会扫描该标头中的文件吗?要获取我的映射和 numSets 变量,我需要遍历我的输入文件。我没有使用头文件,因为我是 C 菜鸟,但如果我理解正确,在我的头文件中,我会创建一个方法来扫描作为命令行参数传递给程序的文本文件.然后,我从文件中获取全局变量,然后将它们作为全局变量传递到我的 .c 项目中?
【解决方案2】:

要拥有具有运行时确定大小的全局缓存结构,请使用:

int mapping, numsets;
struct cache **cache;

和:

void init(int nmaps, int nsets)
{
    cache=malloc(nmaps*sizeof(struct cache *));
    for (int i=0;i<nmaps;i++)
        cache[i]=malloc(nsets*sizeof(struct cache));
    mapping= nmaps;
    numsets= nsets;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-03
    • 2023-03-25
    • 1970-01-01
    相关资源
    最近更新 更多