现在我的问题是,在我可以访问abc
但不能
访问的另一个文件中stud
,我想根据条件更新 stud->address
if(true) {
//update stud-> address
}
我怎么做?
由于abc
指向相同的地址stud
,它们指向内存中的相同位置。其中任何一个都会将您带到存储数据的地方。
这部分:
if(true) {
//update stud-> address
abc->address = xyz->address
}
free(xyz);
free(xyz)
将释放内存位置abc
和xyz
指向。但如果您分配->address
. 如果是这样,它应该是这样的:
free(xyz->address);
// free any other allocated child elements
free(xyz);
这部分:
if(true) {
//update stud-> address
free(abc->address);
abc->address = strdup(xyz->address);
}
free(xyz);
也会出现内存泄漏。strdup
分配内存并复制字符串,请参见此处:
strdup() 函数应返回一个指向新字符串的指针,该字符串是 s1 指向的字符串的副本。返回的指针可以传递给 free()。如果无法创建新字符串,则返回空指针。
所以你还需要:
free(xyz->address);
// free any other allocated child elements
free(xyz);
如果需要做大量的引用和解引用,你可能需要实现一些简单的引用计数机制来管理引用。像这样简单的东西:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char *firstname;
char *lastname;
char *address;
unsigned int ref; // reference counter
} STUDENT;
// Create new object, and initialize it. Allocation should happen only here.
STUDENT* student_new(void) {
STUDENT* obj = (STUDENT *) calloc(1, sizeof(STUDENT));
// add one to the reference counter +1. So far, this object has
// been used only once.
if( obj ) obj->ref = 1;
return obj;
}
// Get a references to and object, never use assignment `a = b`.
STUDENT* student_get_ref(STUDENT* obj) {
// Rather than using `abc = stud`, use this function
// to get a reference to and object. It will
// increase the reference counter by one and
// simply return `obj`.
obj->ref++;
return obj;
}
// Destroy the object and do some clean-up, never use `free` use it instead.
void student_destroy(STUDENT* obj) {
// when the program is done from an object,
// we decrease -1 the reference counter by one,
// if the reference counter hit the 0,
// this means no one is using this object,
// so free it.
printf("[DBG]: ref => %d\n", obj->ref);
if( --obj->ref == 0 ) {
printf("[DBG]: ref => 0, Object deleted\n");
free(obj);
}
}
int main(int argc, char **argv) {
STUDENT *stud = student_new();
STUDENT *abc;
STUDENT *xyz;
abc = student_get_ref(stud);
xyz = student_get_ref(abc);
student_destroy(stud);
student_destroy(abc);
student_destroy(xyz);
return 0;
}
如果你运行它,你会看到内存直到 才被释放stud
,abc
并且xyz
都完成了:
> example.exe
[DBG]: ref => 3
[DBG]: ref => 2
[DBG]: ref => 1
[DBG]: ref => 0, Object deleted
>
此外,它是一种更简洁的内存管理方式,错误更少,所有分配仅在构造函数student_new
中完成,释放在析构函数中完成student_destroy
。您的程序不再需要调用calloc
// malloc
。free