#c #caching #struct #segmentation-fault
#c #кэширование #структура #ошибка сегментации
Вопрос:
Я пытаюсь смоделировать простой кеш. У меня возникла пара проблем. 1) Можно ли сделать длину массива в строке или установить произвольно. Например, с помощью конструктора. 2) При запуске этого кода я получаю ошибку Seg, и я не могу сказать, почему. Я неправильно обращаюсь к массивам?
Заранее благодарю вас.
#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);
}
Комментарии:
1. У вас есть опечатка во внутреннем цикле:
for (int j = 0; i < 5; j ) {
должно бытьfor (int j = 0; j < 5; j ) {
.2. OT: вы объявляете глобальные переменные с именами
line
,set
, иcache
. Я предполагаю, что они вам не нужны. Например, в объявлении forstruct Cache
следуетstruct Cache { Set sets[5]; };
отметить, что finalcache
удаляется.3. Конечно, после
calloc
того, как цикл по новому объекту для установки его в 0 является избыточным.
Ответ №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()
без вмешательства, тогда как второй подход требует перезагрузки x
в случае перераспределения.
Второй подход совместим со всеми версиями C, от реального C вплоть до последней версии стандарта; в то время как первый подход действителен только в некоторых выпусках стандарта и может быть отозван при более позднем выходе из тела стандартов.
Комментарии:
1. Это зависит от стандарта C. Прочитайте о гибких элементах массива — третьем, более современном способе. Для первого случая
x[0]
становитсяx[]