![](/img/trans.png)
[英]Pointer inside struct appears to change when struct is passed by value to function
[英]malloc'd pointer inside struct that is passed by value
我正在 C 中組織一個項目,我必須在其中傳遞可變長度的字節序列,但由於堆可能有限,我試圖限制 malloc 調用。
假設我有一個結構my_struct
,它包含可變長度字節序列ptr
和一個 function my_func
,它創建了my_struct
的一個實例。 在my_func
中, my_struct.ptr
是 malloc'd, my_struct
按值返回。 my_struct
將被其他按值傳遞的函數使用: another_func
。 下面的代碼。
my_struct_destroy
或釋放 malloc 指針時,針對my_struct
的原始或任何副本上某處提供的 memory 泄漏是否“安全”? 具體來說,有沒有什么辦法可以讓another_func
返回時,那個inst.ptr
可以被重寫或懸空?typedef struct {
char * ptr;
} my_struct;
// allocates n bytes to pointer in structure and initializes.
my_struct my_func(size_t n) {
my_struct out = {(char *) malloc(n)};
/* initialization of out.ptr */
return out;
}
void another_func(my_struct inst) {
/*
do something using the passed-by-value inst
are there problems with inst.ptr here or after this function returns?
*/
}
void my_struct_destroy(my_struct * ms_ptr) {
free(ms_ptr->ptr);
ms_ptr->ptr = NULL;
}
int main() {
my_struct inst = my_func(20);
another_func(inst);
my_struct_destroy(&inst);
}
我可以像您一樣安全地傳遞和返回包含按值指針的結構。 它包含ptr
的副本。 調用 function 沒有任何改變。當然,如果another_func
釋放ptr
然后調用者嘗試使用它或再次釋放它,那將是一個大問題。
alloc+free 的局部性是最佳實踐。 只要有可能,讓分配 object 的 function 也負責釋放它。 如果那不可行,malloc 和相同的 object 應該在同一個源文件中。 在不可能的情況下(想想帶有刪除的復雜圖形數據結構),應該清楚地標識管理給定類型對象的文件集合,並記錄約定。 有一種通用技術對分階段工作的程序(如編譯器)很有用,在該階段中分配的大部分 memory 應該在下一階段開始之前釋放。 在這里,memory 只是malloc
由經理大塊編輯。 從這些,管理器分配任何大小的對象。 但它只知道一種釋放方式:一次全部釋放,大概是在一個階段的末尾。 這是一個gcc
的想法:obstacks。 當分配更復雜時,更大的系統會實現某種垃圾收集器。 除了這些想法之外,管理 C 存儲的方法與 colors 一樣多。抱歉,我沒有任何指向引用的指針(雙關語:)
如果你只有一個變長字段並且它的大小不需要動態更新,可以考慮將結構中的最后一個字段做成一個數組來保存它。 這符合 C 標准:
typedef struct {
... other fields
char a[1]; // variable length
} my_struct;
my_struct my_func(size_t n) {
my_struct *p = malloc(sizeof *p + (n - 1) * sizeof p->a[0]);
... initialize fields of p
return p;
}
這避免了單獨釋放可變長度字段的需要。 不幸的是它只適用於一個。
如果您接受 gcc 擴展名,則可以分配大小為零的數組。 在 C 99 中,您可以使用a[]
獲得相同的效果。 這避免了大小計算中的- 1
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.