20 多年前,我對用 C 寫一些小東西有一定的把握,但即使在那個時候,我可能也沒有一直把事情做對。現在我正在嘗試再次學習C,所以我真的是一個新手。
基于這篇文章: 使用 realloc 來收縮分配的記憶體 ,我做了這個測驗,它有效,但讓我煩惱:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int test (char *param) {
char *s = malloc(strlen(param));
strcpy(s, param);
printf("original string : [M] %s \n", strlen(s), s);
// reduce size
char *tmp = realloc(s, 5);
if (tmp == NULL) {
printf("Failed\n");
free(s);
exit(1);
} else {
tmp[4] = 0;
}
s = tmp;
printf("the reduced string : [M] %s\n", strlen(s), s );
free(s);
}
void main(void){
test("This is a string with a certain length!");
}
- 如果我省略了“tmp[4] = 0”,那么我仍然會得到整個字串。這是否意味著字串的其余部分仍在記憶體中,但不再分配?
- c 如何釋放記憶體呢?它是自己跟蹤記憶體還是由作業系統處理?
- 我釋放了 s 字串“free(s)”,我是否還需要釋放 tmp str(它確實指向同一個記憶體塊,但它擁有的(相同)地址可能存盤在另一個記憶體位置上?
這些很可能只是基礎知識,但到目前為止我所閱讀的內容都沒有給我一個明確的答案(包括提到的文章)。
uj5u.com熱心網友回復:
- 如果我省略了“tmp[4] = 0”,那么我仍然會得到整個字串。
您呼叫了未定義的行為。所有字串操作都要求引數是一個以空字符結尾的字符陣列。如果您減小分配的大小,使其不包含空終止符,那么當它試圖找到它時,您正在訪問分配的外部。
這是否意味著字串的其余部分仍在記憶體中,但不再分配?
在實踐中,當你縮小尺寸時,許多實作實際上并沒有重新分配任何東西。他們只是更新簿記資訊,說明分配的長度更短,并回傳原始指標。因此,字串的其余部分保持不變,除非您進行另一個恰好使用該記憶體的分配。
這甚至可能在您增大尺寸時發生。一些設計總是以特定的粒度(例如 2 的冪)分配記憶體,因此如果您增加分配但不超過粒度,則不需要復制資料。
- c 如何釋放記憶體呢?它是自己跟蹤記憶體還是由作業系統處理?
堆管理是 C 運行時庫的一部分。它可以使用多種策略。
- 我釋放了 s 字串“free(s)”,我是否還需要釋放 tmp str(它確實指向同一個記憶體塊,但它擁有的(相同)地址可能存盤在另一個記憶體位置上?
之后s = tmp;,s和 都tmp指向同一個分配的記憶體塊。您只需要釋放其中之一。
順便說一句,初始分配應該是:
char *s = malloc(strlen(param) 1);
您需要為空終止符加 1,因為strlen()這不計算在內。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/356333.html
標籤:C
