C结构未初始化的外部构造函数

问题描述 投票:0回答:2

我有这个'JobSequence'结构,我想在我的main函数中实例化。为此,我创建了一个new_JobSequence()函数,它分配内存并为结构的所有字段赋予适当的值。在这个函数中,根据我的调试器,一切都正确完成。但是一旦我回到我的主要功能,int cost被设置为任意值,baseInstance = 0x0list = 0x1jobSequence之前和之后的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).
}

所以我真的尝试了很多东西,但我真的无法弄清楚这里发生了什么......

谢谢您的帮助。

c pointers scope init
2个回答
1
投票

当你写作

JobSequence jobSequence;

您要求编译器在堆栈上创建JobSequence类型的变量。

所以你不必为此自己保留记忆。

您在调试器中遇到的问题是jobSequence函数中的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(...);                
}

0
投票

您已在主函数中分配了实例。所以你在new_JobSequence()中真正做的只是在堆中分配一些内存,初始化它并且在退出该函数之前永远不会返回任何内容。如果你想保持这个操作流程,你需要将一个双指针传递给你的函数(并在你的主函数中正确分配一个指针,即JobSequence *pJobSequence = NULL)。

© www.soinside.com 2019 - 2024. All rights reserved.