zoukankan      html  css  js  c++  java
  • 【原】结构体包含CString类型成员变量出错的原理

    问题如下:
    我定义了如下的一个结构体:

    typedef struct
    {
       CString csText;
    }MyStruct;


    并有如下的程序段1:
    MyStruct * p=NULL;
    p=(MyStruct *)malloc(sizeof(MyStruct));
    if(!p)
        AfxMessageBox("分配内存失败!");
    else
    {
        p->csText="hello world!";
        free(p);
    }
    执行程序段1,会出现一个内存读取异常,系统提示程序非法read了一个地址。
     
    换成如下写法也是错的:
    MyStruct astruct;
    astruct.csText = _T("ssssss");//会提示内存读取冲突
     
    换成如下就没错:
    MyStruct *p = new MyStruct;
    p->csText = "SSS";
    delete p;
     

    我的疑问:
    (2) 在我的项目中,需要动态给上述的结构体分配内存,需要怎么实现?
     
     
    编程中国论坛c++版主sunkaidong给出的回复(不胜感激):
     
    1,malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。它们都可用于申请动态内存和释放内存。

    2,对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free


    3,因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以一个能完成清理与释放内存工作的运算符delete注意new/delete不是库函数。


    4,C++程序经常要调用C函数,而C程序只能用malloc/free管理动态内存

    new 是个操作符,和什么"+","-","="...有一样的地位. 
    malloc是个分配内存的函数,供你调用的. 


    new是保留字,不需要头文件支持.
    malloc需要头文件库函数支持.

    new 建立的是一个对象,
    malloc分配的是一块内存.

    new建立的对象你可以把它当成一个普通的对象,用成员函数访问,不要直接访问它的地址空间
    malloc分配的是一块内存区域,就用指针访问好了,而且还可以在里面移动指针.
    #include"AFX.H"
    #include "stdio.h"
    #include"stdlib.h"
    typedef struct
    {
         CString csText;
    }MyStruct;

    int main(void)
    {
         MyStruct * p=NULL;
         p=new MyStruct();

         if(!p)
             printf("分配内存失败!/n");
         else
         {      printf("分配内存成功!/n");
               p->csText="hello world!";
               printf("%s",p->csText);
              
         }
         delete p;
         system("pause");
         return 0;
    }
    对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。
    作为对比,看下这个:
    #include"AFX.H"
    #include "stdio.h"
    #include"stdlib.h"
    typedef class
    {
    public:
         CString csText;
    }MyStruct;

    int main(void)
    {
         MyStruct * p=NULL;
         p=(MyStruct*)malloc(sizeof(MyStruct));

         if(!p)
             printf("分配内存失败!/n");
         else
         {      printf("分配内存成功!/n");
               p->csText="hello world!";
               printf("%s",p->csText);
              
         }
         delete p;
         system("pause");
         return 0;
    }
    这个是错的,只申请了空间没初始化对象,没有调用构造函数,没又构造函数得话,怎么能说明这个地方存放这个类得实例呢?是是对象实例,那么你就不能用指针指向,搭建引用,那么也就没办法指向成员了
  • 相关阅读:
    第十三篇:一点一滴学ibatis(二)映射文件
    第十二篇:随手记一下javaBean的setter,getter方法的命名问题
    第十一篇:一点一滴学ibatis(一)
    第十篇:javaScript中的JSON总结
    第九篇:Spring的applicationContext.xml配置总结
    第八篇:ZTree操作总结
    第六篇:fastJson常用方法总结
    第五篇:zTree节点的一些操作,权当备份
    第四篇:java读取Excel简单模板
    测试驱动android
  • 原文地址:https://www.cnblogs.com/wengzilin/p/3151131.html
Copyright © 2011-2022 走看看