日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

老生常谈,正确使用memset

發布時間:2025/3/12 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 老生常谈,正确使用memset 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
前段項目中發現一個問題,程序總是在某個dynamic_cast進行動態轉換時出異常,查了半天才發現問題原來是出在memset的使用上,雖然問題本身顯而易見,但當處于幾十萬行代碼量級中時,就變得不太那么容易定位了。 本文歸納了下使用memset幾個需要注意的地方,雖然內容很簡單,但也希望對大家有所幫助。
1. memset是以字節為單位,初始化內存塊。 當初始化一個字節單位的數組時,可以用memset把每個數組單元初始化成任何你想要的值,比如, [cpp] view plaincopy print?
  • char?data[10];??
  • memset(data,?1,?sizeof(data));????//?right??
  • memset(data,?0,?sizeof(data));????//?right??
  • char data[10]; memset(data, 1, sizeof(data)); // right memset(data, 0, sizeof(data)); // right 而在初始化其他基礎類型時,則需要注意,比如, [cpp] view plaincopy print?
  • int?data[10];??
  • memset(data,?0,?sizeof(data));????//?right??
  • memset(data,?-1,?sizeof(data));????//?right??
  • memset(data,?1,?sizeof(data));????//?wrong,?data[x]?would?be?0x0101?instead?of?1??
  • int data[10]; memset(data, 0, sizeof(data)); // right memset(data, -1, sizeof(data)); // right memset(data, 1, sizeof(data)); // wrong, data[x] would be 0x0101 instead of 1 2. 當結構體類型中包含指針時,在使用memset初始化時需要小心。 比如如下代碼中, [cpp] view plaincopy print?
  • struct?Parameters?{??
  • ??????????int?x;??
  • ??????????int*?p_x;??
  • };??
  • Parameters?par;??
  • par.p_x?=?new?int[10];??
  • memset(&par,?0,?sizeof(par));??
  • struct Parameters {int x;int* p_x; }; Parameters par; par.p_x = new int[10]; memset(&par, 0, sizeof(par)); 當memset初始化時,并不會初始化p_x指向的int數組單元的值,而會把已經分配過內存的p_x指針本身設置為0,造成內存泄漏。同理,對std::vector等數據類型,顯而易見也是不應該使用memset來初始化的。
    3. 當結構體或類的本身或其基類中存在虛函數時,也需要謹慎使用memset。 這個問題就是在開頭項目中發現的問題,如下代碼中, [cpp] view plaincopy print?
  • class?BaseParameters??
  • {??
  • public:??
  • ????virtual?void?reset()?{}??
  • };??
  • ??
  • class?MyParameters?:?public?BaseParameters??
  • {??
  • public:???
  • ????int?data[3];??
  • ????int?buf[3];??
  • };??
  • ??
  • MyParameters?my_pars;??
  • memset(&my_pars,?0,?sizeof(my_pars));??
  • BaseParameters*?pars?=?&my_pars;??
  • ??
  • //......??
  • ??
  • MyParameters*?my?=?dynamic_cast<MyParameters*>(pars);??
  • class BaseParameters { public:virtual void reset() {} };class MyParameters : public BaseParameters { public: int data[3];int buf[3]; };MyParameters my_pars; memset(&my_pars, 0, sizeof(my_pars)); BaseParameters* pars = &my_pars;//......MyParameters* my = dynamic_cast<MyParameters*>(pars); 程序運行到dynamic_cast時發生異常。原因其實也很容易發現,我們的目的是為了初始化數據結構MyParameters里的data和buf,正常來說需要初始化的內存空間是sizeof(int) * 3 * 2 = 24字節,但是使用memset直接初始化MyParameters類型的數據結構時,sizeof(my_pars)卻是28字節,因為為了實現多態機制,C++對有虛函數的對象會包含一個指向虛函數表(V-Table)的指針,當使用memset時,會把該虛函數表的指針也初始化為0,而dynamic_cast也使用RTTI技術,運行時會使用到V-Table,可此時由于與V-Table的鏈接已經被破壞,導致程序發生異常。

    總結

    以上是生活随笔為你收集整理的老生常谈,正确使用memset的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。