1. 程式人生 > >memset用法詳解與實現

memset用法詳解與實現

memest原型 (please type "man memset" in your shell) 

void *memset(void *s,  int c, size_t n); 

memset:作用是在一段記憶體塊中填充某個給定的值,它對較大的結構體或陣列進行清零操作的一種最快方法。

常見的三種錯誤

第一: 搞反了c 和 n的位置. 

一定要記住 如果要把一個char a[20]清零, 一定是 memset(a,  0,  20) 
而不是 memset(a,  20,  0) 

第二: 過度使用memset, 我想這些程式設計師可能有某種心理陰影, 他們懼怕未經初始化的記憶體, 所以他們會寫出這樣的程式碼:

 

char buffer[20]; 

memset(buffer,  0,  sizeof((char) * 20)); 
strcpy(buffer,  "123"); 

這裡的memset是多餘的. 因為這塊記憶體馬上就被覆蓋了, 清零沒有意義. 

第三: 其實這個錯誤嚴格來講不能算用錯memset, 但是它經常在使用memset的場合出現 

int some_func(struct something  *a)


      … 
      … 
      memset(a,  0,  sizeof(a)); 
      … 

:為何要用memset置零?memset( &Address,  0,  sizeof(Address));經常看到這樣的用法,其實不用的話,分配資料的時候,剩餘的空間也會置零的。

答:1.如果不清空,可能會在測試當中出現野值。 你做下面的試驗看看結果() 

char buf[5]; 

CString str, str1; //memset(buf, 0, sizeof(buf)); 

for(int i = 0;i<5;i++)


       str.Format("%d  ",  buf[i]);

       str1 += str ; 


TRACE(“%s\r\n“,str1);

2.其實不然!特別是對於 字元指標型別的,剩餘的部分通常是不會為0的,不妨作一個試驗,定義一個字元陣列,並輸入一串字元,如果不用memset實現清零,使用MessageBox顯示出來就會有亂碼(0表示NULL,如果有,就預設字元結束,不會輸出後面的亂碼)

問:

如下demo是可以的,能把陣列中的元素值都設定成字元1
#include <iostream>

#include <cstring>
using namespace std;
int main()
{
    char a[5];
    memset(a,’1’,5);
    for(int i = 0; i < 5; i++)
      cout<< a[i] <<"  ";
    system("pause");
    return 0;
}
而,如下程式想吧陣列中的元素值設定成1,卻是不可行的
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
    int a[5];
    memset(a, 1, 5);   //這裡改成memset(a, 1, 5 *sizeof(int))也是不可以的.
    for(int i = 0; i < 5; i++)
      cout << a[i] <<"  ";
    system("pause");
    return 0;
}
問題是:

1,第一個程式為什麼可以,而第二個不行?
2,不想要用for,或是while迴圈來初始化int a[5];能做到嗎?(有沒有一個像memset()這樣的函式初始化)

答:

1.因為第一個程式的陣列a是字元型的,字元型佔據記憶體大小是1Byte,而memset函式也是以位元組為單位進行賦值的,所以你輸出沒有問題。而第二個程式a是整型的,使用memset還是按位元組賦值,這樣賦值完以後,每個陣列元素的值實際上是0x01010101即十進位制的16843009。你看看你輸出結果是否這樣? 

2.如果用memset(a, 1, 20);
就是對a指向的記憶體的20個位元組進行賦值,每個都用ASCII為 1 的字元去填充,轉為二進位制後,1就是00000001, 佔一個位元組。一個INT元素是4位元組,合一起就是1000000010000000100000001,就等於 16843009,就完成了對一個INT元素的賦值了。




以下實現一個my_memset()




void my_memset(void s, int c ,size_t n)

{

    char *ret = s;

    if(NULL == s)

    {

         return;

    }



    while(n--)

    {

         *ret++ = (char)c;

    }



    return s;

}

int main(int argc, char *argv[])
{
    char a[10] = {0};
    int i;

    my_memset(a, ‘1’, sizeof(a));

    for(i = 0; i < sizeof(a); ++i)
    {   
        printf("%c ", a[i]);

    }   

    printf("\n"); 
    return 0;
}

相關推薦

memset用法實現

memest原型 (please type "man memset" in your shell)  void *memset(void *s,  int c, size_t n);  memset:作用是在一段記憶體塊中填充某個給定的值,它對較大的結構體

Ansible系列命令用法使用

Ansible命令詳解 Ansible-doc Ansible-playbook Ansible模塊介紹 Ansible系列命令用法與使用 在上一個文章中已經完成了Ansible的安裝,這片文章主要的用來記錄Ansible一些命令的用法詳解及其使用場景。好了非話不多說,‘上菜吧’。

數據結構 - 紅黑樹(Red Black Tree)插入實現(Java)

啟示 dpa con 技術分享 節點數 src 通知 一點 this   最終還是決定把紅黑樹的篇章一分為二,插入操作一篇,刪除操作一篇,因為合在一起寫篇幅實在太長了,寫起來都覺得累,何況是閱讀並理解的讀者。       紅黑樹刪除操作請參考 數據結構 - 紅黑樹(Red

數據結構 - 紅黑樹(Red Black Tree)刪除實現(Java)

replace ati 轉載 之前 9.png one com 四種 簡單   本篇要講的就是紅黑樹的刪除操作       紅黑樹插入操作請參考 數據結構 - 紅黑樹(Red Black Tree)插入詳解與實現(Java)   紅黑樹的刪除是紅黑樹操作中比較麻煩且比較有意

紅黑樹(Red Black Tree)刪除實現(Java)

  本篇要講的就是紅黑樹的刪除操作   紅黑樹的刪除是紅黑樹操作中比較麻煩且比較有意思的一部分。   在此之前,重申一遍紅黑樹的五個定義: 1. 紅黑樹的節點要不是黑色的要不是紅色的     2. 紅黑樹的根節點一定是黑色的     3. 紅黑樹的所有葉子節點都是黑色的(注意:紅黑樹的葉子節點指Nil節點

Zookeeper機制實現

為什麼要有Zookeeper?       電視裡經常會有一些狗血的設定,隊長和副隊長一起出去執行任務,執行完任務後副隊長回來報到了,但是隊長可能因為天氣原因導致航班延期了,暫時回不來,這個時候副隊長左等右等還等不到隊長回來,而且副隊長擔心隊長如

Skip List(跳躍表)原理實現

#include<stdio.h>  #include<stdlib.h>      #define MAX_LEVEL 10 //最大層數      //節點  typedef  struct nodeStructure  {      int key;      int value

樹堆(Treap)圖文實現

1.Treap的定義 樹堆(Treap)是二叉排序樹(Binary Sort Tree)與堆(Heap)結合產生的一種擁有堆性質的二叉排序樹。 但是這裡要注意兩點,第一點是Treap和二叉堆有一點不同,就是二叉堆必須是完全二叉樹,而Treap並不一定是;第二

Android之viewstub用法實現延遲載入

上一篇的佈局中間就用了viewstub這個控制元件,現在來說一下其作用和用法" ViewStub 是一個不可見的,大小為0的View,最佳用途就是實現View的延遲載入,避免資源浪費,在需要的時候才載入View"需要注意的是,載入view之後,viewstub本身就會被新載入

隨機森林 演算法原理實現步驟

#include <cv.h> // opencv general include file #include <ml.h> // opencv machine learning include file #include <stdio.h>

memset用法(轉)

memest原型 (please type "man memset" in your shell)   void *memset(void *s,  int c, size_t n);  memset:作用是在一段記憶體塊中填充某個給定的值,它對較大的結構體或陣列進行清零操作的一種最快方法。 常見的三種錯誤

oracle 分組函式group by正確用法詳細解釋

oracle資料庫 分組函式與group by正確用法詳解與詳細解釋1.查詢時同時查詢了分組函式列和非分組函式列就需要使用group by,但是僅僅查詢分組函式列可以不結合group by使用。 SQL> select TABLESPACE_NAME,sum(user

SVN之Cornerstone用法 解決上傳.a檔案用法

1.在Launchpad中選擇Conerstone檔案    (圖1) 2.出現如下檢視  (圖2) 3.在伺服器目錄區域,點選“+”,新增HTTP Server。  (圖3) 4.選中所新

ssh祕鑰交換實現 diffie-hellman-group-exchange-sha

    ssh的DH祕鑰交換是一套複合幾種演算法的祕鑰交換演算法。在RFC4419中稱為diffie-hellman-groupX-exchange-shaX 的演算法(也有另一種單純的 rsaX-shaX 交換演算法)。本文就以diffie-hellman-group-

AVL樹(二叉平衡樹)實現

AVL樹概念 前面學習二叉查詢樹和二叉樹的各種遍歷,但是其查詢效率不穩定(斜樹),而二叉平衡樹的用途更多。查詢相比穩定很多。(歡迎關注資料結構專欄) AVL樹是帶有平衡條件的二叉查詢樹。這個平衡條件必須要容易保持。而且要保證它的深度是O(logN). AVL的條件是左右樹的高度差(平衡因子)不大於1;並且它

拓撲排序實現

目錄 介紹 拓撲排序演算法分析 拓撲排序程式碼實現 @(目錄) 介紹 拓撲排序,很多人都可能聽說但是不瞭解的一種演算法。或許很多人只知道它是圖論的一種排序,至於幹什麼的不清楚。又或許很多人可能還

#26 Linux kernel(內核)uname、lsmod、modinfo、depmod、insmod、rmmod、modprobe...命令用法

linux kernel(內核)詳解與uname、lsmod、modinfo、depmod、insmod、rmmod、modprobe...命令用法Linux kernel: 內核設計流派: 單內核設計,但是充分借鑒了微內核體系設計的優點,為內核引入了模塊化機制,內核高度模塊化; 內核被模塊化之

PHP中VC6、VC9、TS、NTS版本的區別用法

進行 系統資源 stc 詳解 ron 線程安全 info 啟動 win 1. VC6與VC9的區別: VC6版本是使用Visual Studio 6編譯器編譯的,如果你的PHP是用Apache來架設的,那你就選擇VC6版本。 VC9版本是使用Visual Studio 20

seekg()/seekp()tellg()/tellp()的用法

文件操作 一個 需要 message ret 開頭 origin 部分 rom 本文轉載於:http://blog.csdn.net/mafuli007/article/details/7314917 (在tcp的文件發送部分有應用) 對輸入流操作:seekg()與tell

JavaScript中SetIntervalsetTimeout的用法

sta 對象 show thead ansi out 計時 顯示 設計 在寫H5遊戲時經常需要使用定時刷新頁面實現動畫效果,比較常用即setTimeout()以及setInterval(),但是大家對SetInterval與setTimeout的用法了解嗎,下面通過