Приведение BigStruct к SmallStruct в C (аналогичные структуры со статическими массивами разных размеров) - PullRequest
4 голосов
/ 06 октября 2009

Предполагается, что по какой-то причине вам разрешено использовать статическую память только в программе на Си. У меня есть базовая структура, которую я использую в нескольких местах, определенных ниже:

#define SMALL_STUFF_MAX_SIZE 64

typedef struct {
    /* Various fields would go here */
    ...
    double data[SMALL_STUFF_MAX_SIZE]; /* array to hold some data */
} SmallStuff;

Теперь меня попросили добавить новую функцию, которая привела бы к конкретному случаю, когда мне нужна та же структура, но с гораздо большим массивом. Я не могу позволить себе увеличить массив структуры SmallStuff, так как память слишком тесна. Поэтому я создал специальную версию структуры, определенной ниже, которую я в конечном итоге приводил к (SmallStuff *) при вызове функций, ожидающих указатель на структуру SmallStuff (фактический размер «данных» правильно обрабатывается в этих функциях) *

#define BIG_STUFF_MAX_SIZE 1000000
typedef struct {
    /* Various fields, identical to the ones in SmallStuff would go here */
    ...
    double data[BIG_STUFF_MAX_SIZE]; /* array to hold some data */
} BigStuff;

Очевидно, что правильный способ сделать это - динамически распределять память, но, как сказано выше, я не могу использовать динамическое выделение памяти.

Есть ли побочные эффекты, которые я должен учитывать? Или лучшие способы решения этой проблемы?

Заранее спасибо.

Ответы [ 3 ]

3 голосов
/ 06 октября 2009

То, что вы делаете, прекрасно, хотя и пугает людей, которым не нравятся указатели и кастинг.

Общее решение вашей проблемы состоит в том, чтобы избавиться от BigStuff и SmallStuff и создать единую структуру Stuff с членом размера и двойными * данными, указывающими на выбранный вами массив, вместо того, чтобы рисковать потенциальными ошибками в коде позже или необходимость изменить свои функции, когда вы обнаружите, что вам также нужен MediumStuff. Это дает вам гибкость в использовании любых подходящих размеров.

typedef struct
{
  // the usual

  size_t data_length;
  double *data;
} Stuff;


double bigdata[BIG_STUFF_MAX_SIZE];
Stuff big = { ..., BIG_STUFF_MAX_SIZE, bigdata };
1 голос
/ 06 октября 2009
typedef struct {
    /* Various fields would go here */
    double data[]; /* a flexible array (C99 extension) */
} AnySizeStuff;

typedef struct {
  AnySizeStuff header;
  double smalldata[SMALL_STUFF_MAX_SIZE];
} SmallStuff;

typedef struct {
  AnySizeStuff header;
  double bigdata[BIG_STUFF_MAX_SIZE];
} BigStuff;

Тогда, если x является SmallStuff или BigStuff, вы можете передать & x.header подпрограммам, которые могут принимать либо.

0 голосов
/ 06 октября 2009

Хотя это уродливый код из-за сложности, не должно быть никаких проблем во время выполнения, потому что размеры жестко заданы.

Лучший способ справиться с этим - иметь алгоритмы, для которых не нужно, чтобы у вас было 2 отдельных структуры, отличающихся только размером. Однако я не знаю ваше приложение, поэтому вы лучше знаете, как справиться с этой проблемой.

...