C-структура неинициализирована вне функции построения - PullRequest
0 голосов
/ 25 октября 2018

У меня есть структура 'JobSequence', которую я хочу создать в своей основной функции.Для этого я создал функцию new_JobSequence(), которая выделяет память и присваивает правильное значение всем полям структуры.Внутри этой функции все сделано правильно в соответствии с моим отладчиком.Но как только я возвращаюсь к моей основной функции, int cost устанавливается на произвольное значение, baseInstance = 0x0 и list = 0x1.Адрес jobSequence до и после new_JobSequence() не меняется и совпадает с адресом, используемым внутри функции.Вот объявление структуры, код функции и main:

typedef struct JobSequence{
    Instance* baseInstance;
    List* sequence;
    int cost;
}JobSequence;

void new_JobSequence(Instance* baseInstance, JobSequence* jobSequence){
    jobSequence = malloc(sizeof(JobSequence));
    jobSequence->baseInstance = baseInstance;
    jobSequence->cost = 0;
    list_new(&jobSequence->sequence);
}

int main() {
    int** P = baseInstance();
    Instance instance;
    makeInstanceFromBin(P,10,10,4,&instance);
    printInstance(&instance);
    JobSequence jobSequence;
    setbuf(stdout, 0);
    printf("address : %p\n",&jobSequence);
    new_JobSequence(&instance,&jobSequence);
    setbuf(stdout, 0);
    printf("address : %p\n",&jobSequence);

    Do other stuff (crashes because I try to access the elements of jobSequence which have 0x1 and 0x0 addresses).
}

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

Спасибо за помощь.

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

Вы уже выделили экземпляр в своей основной функции.Итак, что вы действительно делаете внутри new_JobSequence(), это просто выделяете некоторую память в куче, инициализируете ее и никогда не возвращаете ничего до выхода из этой функции.Если вы хотите сохранить этот поток операций, вам нужно передать двойной указатель в вашу функцию (и правильно выделить только указатель в вашей основной функции, т.е. JobSequence *pJobSequence = NULL).

0 голосов
/ 25 октября 2018

Когда вы пишете

JobSequence jobSequence;

Вы просите компилятор создать переменную типа JobSequence в стеке .

Так что вы делаетене нужно резервировать для нее память .

Проблема, с которой вы сталкиваетесь в отладчике, заключается в том, что функция jobSequence in main не модифицируется функцией new_JobSequence.

Вы можете увидеть это с некоторыми следами отладки:

void new_JobSequence(Instance* baseInstance, JobSequence* jobSequence){
    printf("start of %s: js is %p\n", __FUNCTION__, jobSequence);
    jobSequence = malloc(sizeof(JobSequence));

    printf("after malloc, js is %p\n", jobSequence);
    jobSequence->baseInstance = baseInstance;
    jobSequence->cost = 0;
    list_new(&jobSequence->sequence);       
}

Таким образом, чтобы ваша функция работала с переменной, созданной в main, вы должны написать что-то вроде:

void new_JobSequence(Instance* baseInstance, JobSequence* jobSequence)
{
    jobSequence->baseInstance = baseInstance;
    jobSequence->cost = 0;
    list_new(&(jobSequence->sequence));
}

...
int main(void)
{
    /* ... */
    JobSequence jobSequence;
    new_JobSequence(..., &jobSequence);
}

Если вы хотите выделить память в куче для структуры, вы должны следовать этому подходу:

JobSequence *new_JobSequence(Instance* baseInstance){
    JobSequence *js= malloc(sizeof *js);
    js->baseInstance = baseInstance;
    js->cost = 0;
    list_new(&(js->sequence));

    return js;
}

...
int main(void)
{
    /* ... */
    JobSequence *jobSequence = new_JobSequence(...);                
}
...