通过引用传递结构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;
}