2012-11-10 20 views
33

我很明白memset()的定義是什麼。但是,我不明白它的意義。Memset定義和使用

定義:將由ptr指向的內存塊的第一個num字節設置爲指定的值(解釋爲unsigned char)。

那麼這是硬編碼的內存地址值?

memset(&serv_addr,0,sizeof(serv_addr)是我試圖理解的例子。

有人可以請解釋一個非常簡化的方式?

+2

它主要用於初始化結構和數組。 – imreal

+0

所以這就像說數組[價值]?爲什麼不這樣做呢,那麼使用memset有什麼意義呢? –

+0

只有在編譯期間知道'value'的值(這是C/C++)時,纔可以像'array [value]一樣做。 – irrelephant

回答

38

memset()是一個相對簡單的操作非常快的版本:

void* memset(void* b, int c, size_t len) { 
    char* p = (char*)b; 
    for (size_t i = 0; i != len; ++i) { 
     p[i] = c; 
    } 
    return b; 
} 

也就是說,memset(b, c, l)設定起始地址爲b的值cl字節。它只是比上面的實現快得多。

+1

奇怪的是,你有一個C++的初始化程序,但C演員... – Neil

+0

@尼爾:好點 - 我是一個C++人,我意識到我依靠轉換。我將把代碼改爲C和C++。 –

+0

由於編碼,你的函數具有實現定義的行爲,因爲'c'可能超出'char'類型的範圍。您應該將'p'定義爲'unsigned char * p =(unsigned char *)b;'(僅在C++中需要強制轉換)。 – chqrlie

26

memset()通常用於初始化值。如果你在棧上創建的其中之一,像這樣

struct Size { 
    int width; 
    int height; 
} 

struct Size someSize; 

然後在結構中的值將是未定義例如,考慮下面的結構。它們可能爲零,它們可能是上次使用堆棧的那一部分時發生的任何值。所以通常你會遵循該行:

memset(&someSize, 0, sizeof(someSize)); 

當然,它可以用於其他場景,這只是其中之一。只要將它看作是將內存的一部分設置爲特定值的一種方式。

+2

考慮到提問memset是什麼的問題,這個答案比接受的答案要好。 –

3

我想這serv_addr一些struct類型的某些局部或全局變量-perhaps struct sockaddr - (或者一個class)。

&serv_addr正在接受該變量的地址。這是一個有效的地址,作爲memset的第一個參數給出。 memset的第二個參數是要用於填充的字節(零字節)。 memset的最後一個參數是要填充的內存區域的大小(以字節爲單位),在您的示例中,該大小是該變量的serv_addr的大小。

因此,這個電話memset清除全球或本地變量serv_addr包含一些struct

在實踐中,GCC編譯器,當它被優化,將產生聰明的代碼是,通常展開和內聯它(實際上,它往往是一個內置的,所以GCC可以產生很聰明的代碼)。

5

memset是無論數據類型如何都將存儲區域設置爲0的常用方法。可以說memset不關心數據類型,只是將所有字節設置爲零。

恕我直言在C++中應儘量避免做memset,因爲它規避了C++提供的類型安全性,而應該使用構造函數或初始化作爲初始化方法。在類實例上完成的memset也可能會無意中破壞某些東西:

class A 
{ 
public: 
    shared_ptr<char*> _p; 
}; 

上的一個實例memset上面不會做參考計數器遞減正常。

+1

這個答案應該在列表中更高。在C++中使用memset是不安全的。 – mwm314

1

這只不過是將內存設置爲特定值。

以下是示例代碼。這裏的P是指向目標內存的指針,V是目標緩衝區的值,它將被設置爲值V,l是該目標內存的長度,數據。在存儲器

while(L --> 0) 
{ 
    *p++ = V; 
} 
+0

運營商' - >'的好例子,但我對'L'參數的類型持懷疑態度:'unit8_t'應該是'size_t'。 – chqrlie

0

memset-組字節

Synopsis-

#include<string.h> 

無效* memset的(無效* S,INT C,爲size_t N)

描述 - 的memset的( )函數應將c(轉換爲無符號字符)複製到s所指向的對象的前n個字節中。 這裏對於上面的函數,memset()應該返回s值。

+1

此答案如何爲其他5個答案增加一個4年的職位值? –

+0

我正在尋找答案,我從另一個來源知道這個定義。所以認爲這將有助於其他人在尋找這一個。 – Ashit

0

我也找 - 爲什麼要使用memset的

雖然這裏的東西,與我發生了。

我使用了strncpy(dest,source,chars數)並且得到了一些不正確的結果。 雖然我確信目標數組的大小。

所以當我在strncpy之前使用memset時 - 我爲strncpy輸出獲得了很好的正確結果。 我將進一步調查和報告。

+0

恐怕這個答案是完全無意義的:'strncpy',你應該使用它,因爲它不符合你的想法,**在目標數組結束後將目標數組填充到''\ 0'源字符串,如果所述源字符串比目的地短。但是,如果源字符串太長,它**不會終止目標。在調用'strncpy'之前使用'memset'不會改變任何東西。您必須爲大小參數傳遞了不正確的值,例如源字符串的長度,這是常見的錯誤。 – chqrlie

+0

感謝您的評論。 我們可以使用strncpy來實現如下的子串例程: strncpy(one_char_prod_arr [pcount],token.data.scalar.value,1); one_char_prod_arr獲取token.data.scalar.value的第一個字符 –

+0

我建議不要爲此或任何目的使用'strncpy'。您可以使用'memcpy()'來提取字符串的一部分,但確保手動添加空終止符。 – chqrlie