c++ 構造函數 memset 初始化 注意


http://bbs.chinaunix.net/thread-3776603-1-1.html

http://www.dz3w.com/mcu/clanguage/050409//C271.htm

今天遇到個題目,說在類的構造函數使用memset(this,0,sizeof(*this))會產生什么問題?哪些類可以這樣使用?

 

沒有virtual function,沒有vtable,同時class當中沒有包含其他class成員的class可以用這個。

在對象內部刪除對象自身的行為都是不安全的, 永遠不要那么做.

 

memset在c中是用的非常頻繁的初始化函數了,當然也被帶到了cpp當中,因為當有如下類涉及到非常多的成員變量,很多coder經常偷懶改用memset在構造函數當中初始化

如果所有成員變量是簡單的內置類型是沒有問題

 

但是下面幾種情形是不可以這么使用的:

1.類含有虛函數表:這么做會破壞虛函數表,后續對虛函數的調用都將出現異常

2.類中含有C++類型的對象:例如,類中定義了一個list的對象,由於在構造函數體的代碼執行之前就對list對象完成了初始化,假設list在它的構造函數里分配了內存,那么我們這么一做就破壞了list對象的內存。

 

原因是C++與C是不同的。

C++的類雖然兼容C中的結構體,但是他們還是有本質的區別

在C語言中,memset一個結構體是個明智的做法,但是在C++中不是。一個C++類中除了需要空間來存放數據成員之外,還可能保存着虛函數表指針S,偏移量等信息,一但你memset之后全都沒有了。所以這是錯誤的行為。而且memset完全可以用構造函數的初始化列表來代替。

 

 

===================

http://zhidao.baidu.com/question/1173859544995379179.html

string不能使用memset或者memcpy這些低級函數。
你new完后string的構造函數已經調用完畢,你再memset就破壞了他的內部數據不變式。
 
        
 簡而言之就是,因為memset這種低級函數繞過了封裝,可能會觸發意想不到的行為。
============
http://blog.csdn.net/pkueecser/article/details/38962505

struct結構體含有 string類型,

memset(&xx, 0, sizeof(xx)); 訪問xx.string導致段錯誤, 程序異常。花了好久才排查出此問題,謹記! 

不可用memset來初始化帶有string類型的struct ,可用構造函數來實現!!!

http://www.blogbus.com/gcoder-logs/52066919.html

 


http://www.cnblogs.com/luxiaoxun/archive/2012/11/07/2759385.html
復制代碼
#include <iostream>
#include <string>
using namespace std;

typedef struct Test
{
    string name;
    int     a;
}Test;

int main()
{
    Test tTest;
    memset(&tTest, 0, sizeof(Test));
    return 0;
}
復制代碼
 
        

程序會崩潰!
不能把一個含有string型的對象memset,含有CString對象也是如此。
C++里結構就是類,而不是原生的C結構。用memset會把類里的一些必要數據清零。另外需要注意如果類有虛函數,則就有虛表指針,用memset會把虛函數表指針置為0,這樣的類就不會有多態了。

 

 

==================================

#include <iostream>  
#include <string>  
#include <stdlib.h>  
      
using namespace std;  
      
struct flowRecord            
{  
    string app_name;                                                              
    struct flowRecord *next;  
      
};  
      
int main() {  
    flowRecord *fr = (flowRecord*)malloc(sizeof(flowRecord));  
    fr->app_name = "hello";  
    out << fr->app_name << endl;  
    return 0;  
}

  在Linux下用g++編譯后運行試試,會出現“Segmentation fault (core dumped)”,why?

問題就出在給fr指針分配內存的時候,注意這里用的是C中的malloc而不是new,如果你換成new再運行,就不會報錯 了,成功的輸出“hello”,那為什么malloc就不行呢?這就要看malloc()與new()的區別了,關於兩者的區別是程序員面試中屢問不爽的經典面試題,所以相信一般的程序員都知道它們之間有一個非常重要的區別就是:new在分配內存時會調用默認的構造函數,而malloc不會調用。 

而STL的string在賦值之前需要調用默認的構造函數以初始化string后才能使用,如賦值、打印等操作,如果使用malloc分配內存,就不會調 用string默認的構造函數來初始化結構體中的app_name字符串,因此這里給其直接賦值是錯誤的,應該使用new操作符。

這也提示我們用C++開發程序時,就盡量使用C++中的函數,不要C++與C混合編程,導致使用混淆,比如有時候new分配的內存卻用free釋放。

 

 

 

 
        

 

 





免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM