我在主函式中有一個結構陣列,我想保存幾個結構的資料。我正在使用一個函式來接收所需的資料并將其放入函式中定義的結構中。在程序結束時,我回傳這個結構的地址。但是如果我多次呼叫這個函式,它總是定義結構的相同地址,所以我會丟失上一次呼叫的資料。
#include<stdio.h>
struct data {
int day;
};
struct data* Dates(int val);
int main() {
struct data* Dates1[3];
int array[] = { 12, 15, 2021 };
for (int i = 0; i < 3; i ) {
Dates1[i] = Dates(array[i]);
}
}
struct data* Dates(int val) {
struct data Date;
Date.day = val;
return &Date; ///AFTER EVERY CALL TO THIS FUNCTION IT RETURN THE SAME ADDRESS!!!
}
uj5u.com熱心網友回復:
當您呼叫一個函式時,它會創建一個堆疊幀。該函式的區域變數在該堆疊幀內分配。當函式退出時,堆疊幀被“銷毀”。該記憶體可以重復使用。
您看到這種行為是因為每次在回圈中呼叫該函式時,它都會重用相同的記憶體空間。
您不能依賴分配在當前函式呼叫之外的堆疊上的變數的地址的有效性。如果在函式呼叫后需要一個值繼續存在,則需要動態分配它 - 通常使用malloc. 完成后不要忘記free那個記憶。
uj5u.com熱心網友回復:
你必須把你的函式寫成這樣:
struct data* Date = (struct data*) malloc(sizeof(struct data))
Date->day = val;
return Date;
之后,您必須在不再使用指標時呼叫 free() 。(如果不是,這稱為記憶體泄漏)
當您感到困惑時,請記住一個簡單的規則,即您只能回傳指向創建變數指向的呼叫級別的指標。如果您想了解這是為什么,您應該閱讀呼叫堆疊是什么以及堆疊變數如何作業。
uj5u.com熱心網友回復:
如果你不想使用malloc,另一種方法是讓函式接收一個指向未初始化值的指標void Dates(struct data *, int);,然后呼叫者負責記憶體。
#include <stdio.h>
#include <assert.h>
struct data {
int day;
};
static void Dates(struct data *const data, const int val) {
assert(data); /* Defensive debug. */
data->day = val;
}
int main(void) {
int array[] = { 12, 15, 2021 };
struct data dates1[sizeof array / sizeof *array];
for(int i = 0; i < sizeof dates1 / sizeof *dates1; i )
{
Dates(dates1 i, array[i]);
printf("%d: %d\n", i, dates1[i].day);
}
}
這更適合于需要記憶體分配不可知的功能時;在這個例子中,我在堆上而不是動態地保留了記憶體。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/393268.html
標籤:C
下一篇:陣列b等于陣列元素a的位數之和
