【问题标题】:Accessing Structs and Calloc访问结构和 Calloc
【发布时间】:2021-02-01 02:30:15
【问题描述】:

我正在尝试模拟一个简单的缓存。我有几个问题。 1) 是否可以使 Line 或 Set 中的数组长度任意。就像通过使用构造函数一样。 2) 运行此代码时出现 Seg Fault,但我不知道为什么。我错误地访问了数组?

提前谢谢你。

#include <stdio.h>
#include <stdlib.h>

struct Line {
    unsigned int valid;
    unsigned int tag;
}line;

typedef struct Line Line;

struct Set {
    Line lines[5];
}set;

typedef struct Set Set;

struct Cache {
    Set sets[5];
}cache;

typedef struct Cache Cache;

int main(void) {
  Cache *cache = calloc(1,sizeof(Cache));
  
  for(int i=0; i<5; i++){
        for(int j=0; i<5; j++){
            cache->sets[i].lines[j].valid = 0;
            cache->sets[i].lines[j].tag = 0;
        }
    }

  free(cache);
}

【问题讨论】:

  • 您的内部循环中有错字:for (int j = 0; i &lt; 5; j++) { 应该是 for (int j = 0; j &lt; 5; j++) {
  • OT:您正在声明名为 linesetcache 的全局变量。我猜你不想要那些。例如,struct Cache 的声明应为 struct Cache { Set sets[5]; }; 请注意,最后的 cache 已删除。
  • 当然,在calloc之后,循环遍历新对象将其设置为0是多余的。

标签: c caching struct segmentation-fault


【解决方案1】:

有两种惯用的方法来制作可变长度的结构。第一个是:

struct blah {
    int a, b, c;
    char d, e, f;
    short g;
    MyType x[0];
};

要创建这样的结构,您需要:

struct blah *MakeBlah(int n) {
     struct blah *p;
     if ((p = malloc(sizeof *p + sizeof *p->x * n)) != 0) {
          /* whatever */
     }
     return p;
}

另一个是:

struct blah {
    int a, b, c;
    char d, e, f;
    short g;
    MyType *x;
};

struct blah *MakeBlah(int n) {
    struct blah *p;
    if ((p = malloc(sizeof *p + sizeof *p->x * n)) != 0) {
         p->x = (MyType *)(p+1);
    }
    return p;
}

在这两种情况下,在MakeBlah 之后,您都可以随意填写 x[0..n-1] 来满足您的心愿。

第一种方法更简洁,可以在没有干预的情况下存活realloc(),而第二种方法需要在 realloc 的情况下重置x

第二种方法兼容所有版本的C,从真正的C一直到最新的标准;而第一种方法仅在标准的某些排放中有效,并且可能会被标准机构的后续渗出物撤回。

【讨论】:

  • 这取决于 C 标准。阅读flexible array members - 第三种更现代的方式。对于第一种情况,x[0] 变为 x[]
猜你喜欢
  • 2020-03-22
  • 1970-01-01
  • 2011-08-30
  • 2020-11-26
  • 1970-01-01
  • 1970-01-01
  • 2020-10-08
  • 2014-09-14
  • 1970-01-01
相关资源
最近更新 更多