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