簡體   English   中英

C - memset 與免費

[英]C - memset vs free

我對調用 memset 時內存中實際發生的情況與調用 free 時發生的情況感到困惑。

例如,我有一個指向 char* 數組的指針 A

char** A = (char**)calloc(5, sizeof(char*));
int i;
for(i=0;i<5;i++)
{
  //filling
  A[i] = (char*)calloc(30, sizeof(char)); 
  scanf("%s", &A[i]);
}

現在我想重置它我的 char** 指針和它指向的所有元素完全為空

memset(A, 0, 5);

或者

free(A);

有什么不同?

我對 C 有點陌生,所以請用外行的話說謝謝

不同的是memset實際上是設置一塊內存的值,而free返回內存供操作系統使用。

通過使用物理事物進行類比memset(beer, 0, 6)應用於六包啤酒的memset(beer, 0, 6)會將值 '0' 應用於數組beer所有六個成員,而free(beer)將相當於給把六包送給朋友。

memset函數將內存區域設置為請求的值。 請注意,您提供的大小是字節數

free函數釋放分配的內存,因此不能再使用它。 調用free通常不會以任何方式修改內存。 在調用free后使用內存會導致未定義的行為

這兩種方法都不正確,但有些互補。

memset會將緩沖區的內容設置為給定的值,在您的情況下為 0。 這將更改指針的值,這將導致您丟失對已分配緩沖區的引用(在每個A[i] )。

free(A)將釋放 A 指向的緩沖區,但該緩沖區包含指針,並且它們指向的每個緩沖區都不會被釋放。

簡而言之 - memset 不會釋放動態分配的緩沖區,並且 free 不會將其設置為零。

正確的方法是這樣的:

for(i=0;i<5;i++)
{
    // complementary to
    // A[i] = (char*)calloc(30, sizeof(char)); 
    free(A[i]);
}
// complementary to
// char** A = (char**)calloc(5, sizeof(char*));
free(A);
A = NULL; // so no one gets confused...

free釋放內存,這意味着 A 仍將指向相同的內存位置,這現在是無效的。

memset會將 A 當前指向的內存設置為您想要的任何內容。

memset更改內存地址處的內容。 它不會改變內存是否被分配/釋放。

free不會改變內存地址的內容。 它釋放內存塊,使其可供程序回收和重用。 因此,指向該塊的任何指針都會變得無效,並且嘗試訪問內存應該會導致段錯誤(“如果你很幸運”,正如我的教授所說的那樣)。

當您知道將再次訪問該地址的數據時,請使用memset 當您知道數據將不再被訪問並且程序可能會回收該內存時,請使用free

memset() 方法只是用一個給定的字符替換 x 個內存字節,分配的內存由指針 *a 指向;

memset(a, 'a', x);

memset() 方法的原型是:

void* memset(void*, unsigned int, int);

memset()行為與strcpy()類似,但不同之處在於memcpy()按原樣復制數據(字節),但strcpy復制格式化的字符串(因此執行時間比memcpy多)。

然而, free()方法只是釋放內存空間並使其可被占用。

雖然其他答案解釋了差異,但讓我添加一個示例,當 memset() 和 free() 需要按特定順序一起使用時:

如果 malloc 的內存區域用於存儲任何需要擦除以防止其他人窺探它的關鍵/有價值的信息(比如一些與安全相關的東西,如管理密碼或其他一些加密),你會想要首先擦除該內存區域中的內容,然后對其調用 free() 以將該區域的控制權交還給操作系統。

因此,就像 free() 是 malloc() 的對立面一樣,memset(to zero)-then-free() 是 calloc() 的對立面。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM