[英]pointer to a pointer, which is pointing to a memory block, which pointer should be freed?
[英]change the value of a pointer from another pointer which is pointing to the first pointer
我的結構如下:
typedef struct
{
char *firstname;
char *lastname;
char *address;
} STUDENT;
在主程序中
int main() {
stud = (STUDENT *) calloc(1, sizeof(STUDENT));
//I have assinged some values to stud
}
我還有另一個指針,它指向螺柱
STUDENT *abc;
abc = stud;
我不釋放螺柱,因為abc指向它。
現在我的問題是,在另一個我可以訪問abc但沒有stud的文件中,我想根據條件更新stud-> address
if(true) {
//update stud-> address
}
我怎么做?
好的,我忘了補充一下,在函數末尾釋放了新值:
if(true) {
//update stud-> address
abc->address = xyz->address
}
free(xyz);
在這種情況下,abc-> adress將指向空內存,對嗎? 在這種情況下,如何更新abc-> address;
這項工作會:
if(true) {
//update stud-> address
free(abc->address);
abc->address = strdup(xyz->address);
}
free(xyz);
現在我的問題是,在另一個我可以訪問
abc
但沒有stud
,我想根據條件更新stud-> addressif(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
。
如果兩個指針都指向同一個內存,則沒關系,無論您使用哪個指針來更改結構中的值,都將始終對其進行修改。
因此,在您的其他文件中,您可以輕松使用:
abc->address = something;
它將被更新。 當您使用另一個指針stud
,它將顯示您所做的更改。
abc
和stud
存儲相同的值,即malloc/calloc
的內存地址。
C語法abc->lastname
只是仰望的內存地址, lastname
,所以你可以讀/寫它。
因此,您只需使用abc->(<fields>)
進行寫入,程序的另一部分即可讀取更新后的值。
我假設您只有一個線程在進行讀/寫,而多線程I / O是另一種野獸。
如果您有權訪問abc。 然后,您可以執行以下操作:
if(true) {
abc->address = something_new_value; //update stud-> address
}
正如其他人指出的那樣,當您動態分配內存時,也應該可以從其他文件直接訪問它,因為calloc()分配的內存不是來自堆棧。 但是這樣做並不一定是一種好的編碼習慣,因為您可能會不清楚哪個模塊在何時何地訪問內存。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.