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