Динамическое размещение массива типа структуры - PullRequest
0 голосов
/ 17 ноября 2018

У меня проблема с добавлением элемента (структуры) в динамический массив, который находится в структуре.

Здесь основная структура

struct testfw_t
{
    char* program;
    int timeout;
    char *logfile;
    char *cmd;
    bool silent;
    bool verbose;
    struct testTab *tests;
};

Здесь массив

struct testTab 
{
    int size;
    struct test_t  *oneTest;        
};

и, наконец, добавляемый элемент:

struct test_t
{
    char *suite;        /**< suite name */
    char *name;         /**< test name */
    testfw_func_t func; /**< test function */
};

Так что мне нужно добавить struct test_t в массив testTab в struct testfw_t, и я потерян во многомиз malloc и realloc вызовов.

PS: инициализация основной структуры, если она может быть полезной, которая работает:

struct testfw_t *testfw_init(char *program, int timeout, char *logfile, char *cmd, bool silent, bool verbose){

    struct testfw_t *t;
    t = malloc(sizeof(struct testfw_t));

    t->program = program;
    t->timeout = timeout;
    t->logfile = logfile;
    t->cmd = cmd;
    t->silent = silent;
    t->verbose = verbose;
    t->tests = malloc(sizeof(struct testTab));
    t->tests->size=0;
    t->tests->oneTest=NULL;

    return t;
}

РЕДАКТИРОВАТЬ: Что я пытаюсь

struct test_t *nouveau;

nouveau->suite = suite;
nouveau->name = name;
nouveau->func=func;

//fw->tests=realloc(fw->tests->oneTest,(fw->tests->size+1) * sizeof(struct testTab));

fw->tests->oneTest=malloc((fw->tests->size+1) * sizeof(nouveau));

fw->tests->oneTest[fw->tests->size+1] = *nouveau;   
fw->tests->size++;

return nouveau;

1 Ответ

0 голосов
/ 17 ноября 2018

В вашем коде nouveau никуда не указывает, когда вы получаете к нему доступ с помощью ->.Это неопределенное поведение.

Вместо этого просто увеличьте массив с помощью realloc, а затем присвойте последний элемент:

// make array larger by one
fw->tests->oneTest = realloc(fw->tests->oneTest,
                     (fw->tests->size + 1) * sizeof(struct testTab));

// to do: test success

// assign values to new slot
fw->tests->oneTest[fw->tests->size]->suite = strdup(suite);
fw->tests->oneTest[fw->tests->size]->name = strdup(name);
fw->tests->oneTest[fw->tests->size]->func = func;

// increase the array size
fw->tests->size++;

Это код выделения, который не может восстановить старые данные после сбоя выделения,Единственное полезное, что нужно сделать в случае неудачи - это выйти с ошибкой.Джонатан Леффлер отмечает, что этого можно избежать, сначала выделив временный указатель, и восстановив старые данные в случае неудачного выделения.(Конечно, вам все еще нужно решить, что делать в таких случаях.)

Я использовал (нестандартную, но широко доступную) функцию strdup здесь, чтобы скопировать содержимое строк.Ваш вариант работает, если строки гарантированно «живут» до тех пор, пока ваша структура и отличаются, или если они являются литералами, но обычно лучше хранить копии.

...