首页 > 试题广场 >

使用 char* p = new char[100]申请一段

[单选题]
使用 char* p = new char[100]申请一段内存,然后使用delete p释放,有什么问题?
  • 会有内存泄露
  • 不会有内存泄露,但不建议用
  • 编译就会报错,必须使用delete []p;
  • 编译没问题,运行会直接崩溃
当用delete来释放用new int[]申请的内存空间时,由于其为基本数据类型没有析构函数,所以使用delete与delete []相同,两者都会释放申请的内存空间,若是自定义的数据类型,有析构函数时,用new []申请的空间,必须要用delete []来释放,因为要delete []时会逐一调用对象数组的析构函数,然后释放空间
发表于 2015-05-16 11:56:57 回复(4)
B
C++告诉我们在回收用 new 分配的单个对象的内存空间的时候用 delete,回收用 new[] 分配的一组对象的内存空间的时候用 delete[]。
关于 new[] 和 delete[],其中又分为两种情况:(1) 为基本数据类型分配和回收空间;(2) 为自定义类型分配和回收空间。
基本类型的对象没有析构函数,所以回收基本类型组成的数组空间用 delete 和 delete[] 都是应该可以的;但是对于类对象数组,只能用 delete[]。
   所以一个简单的使用原则就是:new 和 delete、new[] 和 delete[] 对应使用。
发表于 2015-06-17 21:09:41 回复(1)

如果是内置类型,因为不调用析构函数。不会造成内存泄漏,但应该避免这种错误的用法。下来我主要分析一下用户自定义类型。

class A
{
};

int main()
{
     A* ptr = new A[10];
     delete ptr;
     return 0;
}

这段代码是可以通过编译的,但造成内存泄漏是必然的。


那么如果我在A类中显式的给出析构函数呢?
这时候程序直接就崩掉了,想象为什么。
new[]在开辟空间的时候会多开辟四个字节来保存析构的次数。
如果没有显式给出析构函数,编译器自己做了优化,所以没有报错,而一旦你显式给出析构函数,系统便直接崩溃了,先来探究崩溃的缘由。
图片说明
如图所示,如果用new[]出来的字节,在析构的时候它会将指针调整到最开始开辟空间的位置,将多开辟的四个字节也删除了。
就像上面的代码示例,开辟空间的时候从1的位置开始,调用析构却从2的位置开始释放,当然,这是崩溃的原因,因为开始析构的地址是不对的。
仅是为了理解这部分,我们给指针减去四个字节,让它从正确的地址开始析构,这时候,编译成功通过了。
代码如下,我们看下结果。
class A
{
public:
    ~A()
    {
        std::cout <<" ~A()" << " ";
    }
};

int main()
{
    A* ptr = new A[10];
    ptr = ptr - 4;//c++中空类的大小为1,所以这里直接这样调整指针指向了。
    delete ptr;
    system("pause");
    return 0;
}

图片说明
虽然调整了指针指向,让它可以从正确的地址开始析构,但是却只调用了一次析构。

基于上面指出的问题,所以尽量在使用时配对使用,以免造成内存泄漏。
差点忘了说,如果匹配使用,这里是会调用10次析构的喔。

上面是前段时间学习中遇到的这个问题,就自己整理了一下,今天刚好看到这个题,发表下自己的看法,如果有说的不对的地方还请指正。
编辑于 2018-04-08 10:39:02 回复(6)
基本类型的对象没有析构函数,所以回收基本类型组成的数组空间用 delete 和 delete[] 都是应该可以的;但是对于类对象数组,只能用 delete[]。
发表于 2016-07-10 19:43:46 回复(1)
这篇博文介绍的很清晰。
http://blog.csdn.net/cbnotes/article/details/38900799
发表于 2016-05-28 16:10:24 回复(0)
the answer is B ,  if the type is int,char,float, both delete[]p and delete p are ok,but if the type is class object, the answer will be A
发表于 2015-03-26 13:10:35 回复(0)
选B,不会有内存泄露,但不建议用。
C++中,我们在回收分配的内存空间时,一个基本的原则是:用 new 分配的单个对象,回收内存空间时用 delete,用 new[] 分配的一组对象,回收内存空间时用 delete[]。 
但是对于数组,又分为两种情况:(1) 为基本数据类型分配和回收空间;(2) 为自定义类型分配和回收空间。
基本类型的对象没有析构函数,所以回收基本类型组成的数组空间用 delete 和 delete[] 都是可以的;但是对于自定义类对象数组,只能用 delete[]。
所以为了记忆的方便,我们可以使用统一的原则:new 和 delete、new[] 和 delete[] 对应使用。这样在团队协作时也有利于别人去理解我们的程序。
发表于 2018-05-07 10:19:15 回复(0)
这题目选哪个作为答案,应该把重点放在“但不建议使用”上,而不是只讨论”会不会有内存泄露“。
题目的用法本身是"undefined behavior",是C++标准未定义行为,但是C++编译器的具体实现,看起来都不会给编译错误。
但是编译器不报错不表示我们应该使用它。相反,这种擦边球的做法应该极力避免。

编译和运行会不会有问题,写代码试试就知道了,记住就好了,对于基本类型,题目的做法肯定可以运行,delete[] p的话会把数组各元素逐一调用析构函数,delete p则只调用第一个元素的析构函数。 内存泄露?这个是编译器的具体行为了,gcc下是没有内存泄露的,是一口气释放整块new出来的内存的。但是这只是gcc的一厢情愿。
发表于 2017-09-22 14:35:51 回复(0)
答案:A
解析:
c++ primer 第四版 4.3.1节: 理论上,回收数组时缺少空方括号对,至少会导致运行时少释放了内存空间,
从而产生内存泄漏(memory leak)。对于某些系统和/或元素类型,有可能会带
来更严重的运行时错误。因此,在释放动态数组时千万别忘了方括号对。
发表于 2016-06-28 21:00:17 回复(0)
@or头像 @or
为什么不建议用?new了不就是要delete的吗
发表于 2019-05-04 16:36:29 回复(0)
内置数据类型不会出现内存泄漏。
编辑于 2019-01-02 21:24:34 回复(0)
如果是new[]对象,delete,那么会崩溃。 又是一道垃圾题。
发表于 2017-09-19 10:58:31 回复(0)
C++告诉我们在回收用 new 分配的单个对象的内存空间的时候用 delete,回收用 new[] 分配的一组对象的内存空间的时候用 delete[]。 
关于 new[] 和 delete[],其中又分为两种情况:(1) 为基本数据类型分配和回收空间;(2) 为自定义类型分配和回收空间。
基本类型的对象没有析构函数,所以回收基本类型组成的数组空间用 delete 和 delete[] 都是应该可以的;但是对于类对象数组,只能用 delete[]。
   所以一个简单的使用原则就是:new 和 delete、new[] 和 delete[] 对应使用。
发表于 2017-09-02 14:46:11 回复(0)
推荐看看此篇博文 http://blog.csdn.net/cbnotes/article/details/38900799
发表于 2016-12-08 14:40:26 回复(0)
#include <iostream>
using namespace std;

int main() {
    int *p = new int[100];
    int *temp = p;
    for (int i = 0; i < 100; ++i) {
        p[i] = i;
        //cout << *p++ << " ";
    }
    p = temp;
    for (int i = 0; i < 100; ++i) {
        cout << p[i] << " ";
    }
    delete[] p;
    //delete p;
    return 0;
}
不管是delete p 还是,delete[] p,  都有相同的错误码
Process finished with exit code -1073740940 (0xC0000374)
发表于 2016-08-29 11:11:32 回复(2)
由于内置数据类型没有构造、析构函数,所以在针对内置数据类型时,释放内存使用delete或delete[]的效果是一样的

ref:
http://book.51cto.com/art/201202/317620.htm
发表于 2016-06-29 16:20:47 回复(0)
我们可以考虑new跟delete的本质是malloc/free,
那么这段代码可以转换为
char *p = (char *) malloc(100*sizeof(char));
if(p)
    free(p);
这样理解的话就不会发生内存泄露的。
其实new/new[],delete/delete[] 的区别在于数组里的对象是否有析构函数,如果没有析构函数的话这两个还是没什么区别的(PS. 个人理解)
详见本人博文http://foocoder.github.io/c/c++/2016/05/26/Look-Inside-Memory-Leak/
发表于 2016-05-26 20:57:28 回复(0)
char *p=new char[100] delete p 在没有析构函数的时候,编译不会出问题,运行也正常,只是会有内存泄露 如果有析构函数,编译正常,运行会崩溃
发表于 2016-05-19 19:36:02 回复(0)
因为CHAR是内部类型,所以用delete和delete[]都可以释放相应的数组空间内存。这时两都的使用情况是一样的。
发表于 2016-05-18 17:11:50 回复(0)
答案是D
C++为指针提供“ delete []表达式 ”释放指针所指向的数组空间。在关键字 delete 和指针之间的空方括号对是必不可少的: 它告诉编译器该指针指向的是自由存储区中的数组,而并非单个对象。 如果遗漏了空方括号对,这是一个编译器无法发现的错误,将导致程序在运行时出错。
发表于 2014-12-04 09:34:25 回复(1)