通过引用传递结构vs在malloc之后传递结构

通过引用传递结构vs在malloc之后传递结构,c,struct,malloc,C,Struct,Malloc,这两种方法在数据可见性和内存开销方面有什么区别(其他任何区别都会很好): 通过引用传递本地结构 向分配的内存传递指针 typedef结构学生数据{ 字符名[30]; 智力得分; }学生资料; 无效填充值(学生数据){ snprintf(数据->名称,30,“Howard”); 数据->得分=20; 回来 } 内部主(空){ 学生数据记录; 学生数据*ptr=NULL; fill_values(&record);//通过引用传递结构 ptr=(学生数据*)malloc(学生数据大小); 如果(!p

这两种方法在数据可见性和内存开销方面有什么区别(其他任何区别都会很好):

  • 通过引用传递本地结构
  • 向分配的内存传递指针
  • typedef结构学生数据{
    字符名[30];
    智力得分;
    }学生资料;
    无效填充值(学生数据){
    snprintf(数据->名称,30,“Howard”);
    数据->得分=20;
    回来
    }
    内部主(空){
    学生数据记录;
    学生数据*ptr=NULL;
    fill_values(&record);//通过引用传递结构
    ptr=(学生数据*)malloc(学生数据大小);
    如果(!ptr){
    printf(“NOMEM”);
    返回0;
    }
    fill_values(ptr);//分配内存后传递
    如果(ptr){
    免费(ptr);
    }
    返回0;
    }
    
    对于局部变量,内存开销将完全存在于该线程的堆栈中。如果您在嵌入式系统中使用大型结构,这可能会成为一个问题,因为您有堆栈溢出的风险。通常只使用请求的字节数,但堆栈空间可能会受到限制。(我使用的某些应用程序的堆栈为512字节或更少)

    在使用malloc的情况下,您是从堆中分配内存。这避免了堆栈大小的问题,但增加了在完成时释放内存的要求

    可见性由存储指针的变量决定


    将局部变量传递给单独的线程是非常危险的,如果局部变量变得无效(例如由于函数返回),则可能导致未定义的行为。

    传递局部结构肯定会更快,程序可以在编译时执行groovey操作。从机器代码的角度来看,本地结构实际上是一个恒定的内存地址。 当您开始使用malloc时,必然会有处理开销,同时也存在空间问题。虽然这两个结构是相同的,但malloc可能会“使用”比sizeof(struct)更多的内存来存储数据。malloc还在每个页面上保留空间来维护和内存地址大小分配的内存查找表,这允许free只需要一个地址作为参数

    最大的问题之一是开发时引入malloc和free-to-programs会增加出现bug的机会,尤其是分段错误。没有提到难以追踪的“隐形”内存泄漏错误。
    但是使用malloc和calloc是处理用户输入的唯一方法,你永远不知道他们将输入多少数据,比如说2kb的文本输入缓冲区很容易被对fgets的调用所填满

    什么让你觉得有区别?这应该是一样的,我看不到任何区别(除了变量包含的内容)。你确定你理解什么是引用以及指针有什么区别吗?顺便说一句,C中没有引用,只有C++@adizone-是的,对于全局变量,你需要malloc。关于程序结束时是否需要释放内存。答案是肯定的,你真的应该这样做。虽然更健壮的操作系统会跟踪每个进程的内存,并在最后自动释放内存,但并非所有操作系统都会这样做。清理自己的烂摊子是个好习惯。谢谢。就可见性而言,只要函数不返回,本地地址
    &record
    是否在程序中的任何地方都有效?如果函数返回,malloc版本是否正确?如果您使用多个线程,我强烈建议您使用malloc,并在清理线程时释放内存。至于堆栈的可见性,如果它在同一个进程中,只要函数不返回,就不应该有任何问题。以空闲循环为例,可以利用这一点,剥离所有线程,然后使用空闲线程堆栈中每个线程使用的信息进行循环。只要空闲循环在您返回之前加入线程,您就应该没事了。关键是确保当函数返回时,没有任何东西(我的意思是没有任何东西)正在使用该数据。感谢@DAhrens的解释。非常好的解释。谢谢
    typedef struct student_data_t_ {
        char name[30];
        int score;
    } student_data_t;
    
    void fill_values (student_data_t *data) {
        snprintf(data->name, 30, "Howard");
        data->score = 20;
        return;
    }
    
    int main (void) {
        student_data_t record;
        student_data_t *ptr = NULL;
    
        fill_values(&record); // <1> passing the struct by reference
    
        ptr = (student_data_t *)malloc(sizeof(student_data_t));
        if (!ptr) {
            printf("NOMEM");
            return 0;
        }
    
        fill_values(ptr);  // <2> passing after allocating memory
    
        if (ptr) {
            free(ptr);
        }
    
        return 0;
    }