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釋放。