【问题标题】:C structure uninitialized outside contruction functionC结构未初始化的外部构造函数
【发布时间】:2019-03-30 04:30:01
【问题描述】:

我有这个“JobSequence”结构,我希望在我的主函数中实例化。为此,我创建了一个 new_JobSequence() 函数,该函数分配内存并为结构的所有字段提供适当的值。在这个函数内部,一切都根据我的调试器正确完成。但是一旦我回到我的主函数int cost 被设置为任意值baseInstance = 0x0list = 0x1jobSequencenew_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


    【解决方案1】:

    当你写作时

    JobSequence jobSequence;
    

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

    所以你不必为它自己预留内存

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

    【讨论】:

    • 您需要在 new_JobSequence() 中添加return js;
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2015-08-08
      • 1970-01-01
      • 2018-06-30
      • 1970-01-01
      • 1970-01-01
      • 2011-01-06
      • 1970-01-01
      • 2021-12-08
      • 1970-01-01
      相关资源
      最近更新 更多