程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 實戰c++中的string系列--不要使用memset初始化string(一定別這麼干)

實戰c++中的string系列--不要使用memset初始化string(一定別這麼干)

編輯:C++入門知識

實戰c++中的string系列--不要使用memset初始化string(一定別這麼干)


百度百科第一次這麼給力:

void *memset(void *s, int ch, size_t n);
函數解釋:將s中前n個字節 (typedef unsigned int size_t )用 ch 替換並返回 s 。
memset:作用是在一段內存塊中填充某個給定的值,它是對較大的結構體或數組進行清零操作的一種最快方法。

memset() 函數常用於內存空間初始化:
 

 char str[100];
 memset(str,0,100);

用來對一段內存空間全部設置為某個字符,一般用在對定義的字符串進行初始化為‘

memset(a, '\0', sizeof(a));

memcpy用來做內存拷貝,你可以拿它拷貝任何數據類型的對象,可以指定拷貝的數據長度:  

char a[100], b[50];
memcpy(b, a, sizeof(b)); //注意如用sizeof(a),會造成b的內存地址溢出。

strcpy就只能拷貝字符串了,它遇到’\0’就結束拷貝:
  

char a[100], b[50];
strcpy(a,b);

如用strcpy(b,a),要注意a中的字符串長度(第一個‘\0’之前)是否超過50位,如超過,則會造成b的內存地址溢出。
  

下面開始:

class Material
{
public:
    Material(){ setDefaults();}
    void setDefaults(){ memset(this,0,sizeof(*this));}
    int mark;
    char materialName[256]; // material name
    Vector3 ambient;    // ambient
    Vector3 diffuse;    // diffuse
    Vector3 specular;   // specular
    int shininess;  //
    float alpha;    //
    bool isSpecular;

char textureName[256];  // texture name
char textureTransName[256]; // transparent texture name

};

這段代碼完美無瑕。再看看下面的:

class Material
{
public:
    Material(){ setDefaults();}
    void setDefaults(){ memset(this,0,sizeof(*this));}
    int mark;
    std::string materialName;   // material name
    Vector3 ambient;    // ambient
    Vector3 diffuse;    // diffuse
    Vector3 specular;   // specular
    int shininess;  //
    float alpha;    //
    bool isSpecular;

std::string textureName;    // texture name
std::string textureTransName;   // transparent texture name
};

上面的代碼會造成內存洩露:
所以對於C++的std::string來說,要使用C++風格的初始化。

在網上看到這樣一條評論,覺得有道理:
任何類都不能用memset, 一旦暴力,就等於你強奸了她的內部數據,她已經崩潰了

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved