[昏了]还是关于内存释放的问题,new 和 delete咋就这么烦呢?

solobird 2005-07-04 04:35:58
CString* p = new CString[4000];
for(int i = 0; i<4000; i++)
{
p[i] = "LLLLLLLLLLLLLLLLLLLL";
}
delete []p;

CString* p = new CString[4000];
for(int i = 0; i<4000; i++)
{
p[i] = 'A';
}
delete []p;

-------------------------------------------------
最后的delete []p;换成 delete p;为什么CString就出错,而char的就不出错啊?而且Char的那个居然还没有内存泄漏的说!昏了!还有好像不能指定其释放其中的某一个元素。譬如 delete (p+100);
...全文
412 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
daseny 2005-07-10
  • 打赏
  • 举报
回复
to jishufenxi(天高云淡) :
在gcc中,delete只会调用数组第一元素的析构,必须用delete []才会为每一个元素调用析构,已验证。
会思考的草 2005-07-06
  • 打赏
  • 举报
回复
delete[][]p?哈哈瞎猜的。
xing_xing_xing 2005-07-05
  • 打赏
  • 举报
回复
值类型的对象可以混用这样
1.配对
char *p = new char[5];
delete []p;
2.配对
char *p = new char;
delete p;
3.混用
char *p = new char[5];
delete p;
4.混用
char *p = new char;
delete []p;
值类型就是没有显式析构的类型,包括基本类型(char,int,指针等等),类类型,结构类型,
对于类/结构类型它的成员也不能包括显式析构函数。
其他的都不可以混用。因为具体实现就是这样的。有析构函数的编译器会生成调用数组每个元素的析构函数的代码,delete []先调用每个的析构函数,然后再释放内存,而值类型的是直接释放内存。
怎么实现的可以自己调试观察了

总之不要混用。

1、居然可以这样char p = new char[0];
2、得到new分配数组的个数
*(((int*)p) - 1) 就是数组元素的个数
ricky20045 2005-07-05
  • 打赏
  • 举报
回复
是的,用new[]申请了一块空间,就用delete[]释放空间。
用malloc,就用free.
daseny 2005-07-05
  • 打赏
  • 举报
回复
to jishufenxi(天高云淡)
一般类的方法是静态代码,普通对象内成员才是动态分配内存吧。
daymist 2005-07-05
  • 打赏
  • 举报
回复
既然能用CString 就直接用CStringArray,简单方便。
你的问题:数组指针的删除当然delete P[]
hasgone 2005-07-05
  • 打赏
  • 举报
回复
p[i] = 'A'!!!!!!
char 当然不会错了
---------------------------------------
双击一个文件的时候,
和该文件关联的程序会自动运行,
请问在关联的应用程序中怎样获得该文件名?(不用mfc的doc-view)
谢谢!
--- 初来乍到,还不会发帖,只好借鸡下蛋,恳请原谅!

jishufenxi 2005-07-05
  • 打赏
  • 举报
回复
to lsgt()
delete 和delete[]都会导致每一个对象的析构函数被调用
goodboyws 2005-07-05
  • 打赏
  • 举报
回复
注意用delete[] 就行了
lsgt 2005-07-05
  • 打赏
  • 举报
回复
最直接的解释就是:delete[]会为数组内的每个成员调用它的析构函数,而delete则不会。
jishufenxi 2005-07-05
  • 打赏
  • 举报
回复
to daseny(胡杨)
也许我说的不是很明白。方法确实是编译时就确定的静态代码,但是“类”和“对象”是通过指针指向“方法”的,这个指针是随着构造初始化的,对象析构时“类”的指针列表也被释放了,delete 操作删除一个实例之后就释放“类”的指针列表,而delete[]删除完所有实例之后才释放“类”的指针列表。
这个问题涉及到c++的内存管理核心机制,我也不是特别清楚,欢迎拍砖,共同学习。
an_bachelor 2005-07-05
  • 打赏
  • 举报
回复
以前我也发过这个关于这个问题的帖 后来根据实验 简单类型用错误的分配方式也比较难出错 即使重复许多遍 但是反复用错误的方式new\delete大内存块 还是有出错的机会 至于为什么那次没讨论出个所以然来
wallgrid 2005-07-05
  • 打赏
  • 举报
回复
数组使用delete []
使用delete (p+100);的人不知道new的机制
char* psz = new char[100];
系统会记录 psz 的地址
当释放时系统知道释放哪些内存!



魔芋 2005-07-04
  • 打赏
  • 举报
回复
用CStringArray/CStringList好不好
jishufenxi 2005-07-04
  • 打赏
  • 举报
回复
其实楼上说的都不正确,楼主一定要深究这个问题的话,请做如下测试:
struct CTemp
{
int a;
int b;
void c(void){};
CTemp(){};
~CTemp(){};
};

CTemp* p = new CTemp[4];
for(int i = 0; i<4; i++)
{
p[i].a = 'A';
}
delete p;
执行上面的代码,就会出现错误。如果把析构函数注释掉,就可以正常运行,什么原因呢?这与c++的内存管理机制有关,类的构造函数和析构函数保存在“类”的结构中,实例在构造和析构的时候就调用类结构的构造析构函数,所以每delete一个实例都会调用析构函数,当你delete对象实例时,响应的类结构空间也会被释放,所以类析构函数也就不存在了,而delete[]知道析构的是数组,直到每一个实例析构完毕之前,类的空间是不会被析构的。不知道我说的清楚么?
oyljerry 2005-07-04
  • 打赏
  • 举报
回复
最好养成new [] 了,就delete [] 的习惯
gooyan 2005-07-04
  • 打赏
  • 举报
回复
CString 本身就有buffer,releasebuffer方法函数,你查查msdn
皮皮鲁 2005-07-04
  • 打赏
  • 举报
回复
同意 Fzergling(十二年的轮回) ( ) 信誉:98
vicky_jam 2005-07-04
  • 打赏
  • 举报
回复
CString* p = new CString[4000];

p[i] = 'A';


这样都能玩~:)老大~

就你觉得这个事有意思吗~?:)

你想实现这个的话,定义char 就行~ 用不着这么大材小用:)
Zhymax 2005-07-04
  • 打赏
  • 举报
回复
1.int *p = new int[10];
2. struct st{
int a;
int b;
};
st *p = new st[10];

3. CString *p = new CString[10];

对于前两种情况,由于对象没有构造和析构函数,调用new 和 delete 只是获得和释放空间,
delete p; 和 delete []p;效果一样;

但是对于第三种情况,new和delete在内部处理上是不一样的,在创建和释放时分别调用构造和析构函数;如果只是单纯的调用delete p;只有第一个对象会被释放,所以必须使用[]来指明是一个数组对象;其实在老的c++语法中连数组的个数都必须说明delete [10]p(现在还是兼容);后来的版本才简化为delete []p;
加载更多回复(6)

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧