我学习用C动态内存分配++和关键字new
和new[]
被提及。 据说,以使用户在运行时,以指定的内存分配的大小,与简单地声明变量或阵列,以在源代码中的固定大小。
我不理解这个概念。 它是如何工作的? 我只需要在观念澄清和示例将是有益的!
我学习用C动态内存分配++和关键字new
和new[]
被提及。 据说,以使用户在运行时,以指定的内存分配的大小,与简单地声明变量或阵列,以在源代码中的固定大小。
我不理解这个概念。 它是如何工作的? 我只需要在观念澄清和示例将是有益的!
所以,如果你想在10个整数数组,你会写:
int arr[10];
但是,如果你想要做这样的事情是什么;
cout << "How many?";
cin >> num;
int arr[num];
那么,C ++语言不允许。 相反,你必须做的:
int *arr = new int[num];
以创建数组。 而后来,您必须在[1]使用:
delete [] arr;
释放内存。
那么,如何工作的呢? 当你调用新的C ++运行时库会找出多少空间[你没有写,构成了C ++的基本代码] num
整数占用,并找到在内存中的一些空间。 我不打算进入细节“你怎么找到一些记忆”。 现在,只要相信我,有一个可用于一些整数存储在一些可用内存的某个地方。
当你再打delete
,同样的内存归还给它原来的内存“池”或“堆”。
当然,如果你有,比如说,256 MB的内存的计算机,并尝试寻求空间来存储2.5亿整数,记住,一个整数占用多于一个字节的轴承,它不会去上班了 - 有没有“神奇”在这里 - 在内存仍然局限于有多少是在机器可用....你必须要确定程序的权利,当它的运行,有多少内存需要,而不必编写程序时决定。
编辑:这通常是最好的“隐藏”使用为这个目的有用的已经存在的“盛载”和“包装类”任何内存分配。 例如:
std::vector<int> arr;
将工作作为整数变量的存储,你永远不用担心释放内存,或者甚至不知道你需要多少你已经有存储在他们面前。
std::shared_ptr<int> arr = new int[num];
另一种情况下,如果当“shared_ptr的”是不再使用[它追踪共享的指针类里面,所以你永远需要关心释放内存。
[1]如果你不想内存泄漏,并且它的“不良作风”内存泄漏。 不做,如果你做的任何人开心。
我已经看到了关于内存分配在C ++中很多帖子,关于“新的运营商”与“运营商新的”的问题,有关问题new int(100)
VS new int[100]
有关内存初始化的问题......我认为应该有汇总清楚一劳永逸,而我选择了这个问题写这个总结的一切答案。 它是关于动态内存分配,在运行时堆即分配。 我也提供了一个简要的实现 (公共领域)。
动态内存分配主要功能:
<cstdlib>
我们有主要malloc
和calloc
和free
。 我不会谈论realloc
。 <new>
),我们有: new T( args )
new (std::nothrow) T( args )
delete ( T* )
new T[ size_t ]
new (std::nothrow) T[ size_t ]
delete[] ( T* )
new (void*) T( args )
new (void*) T[ size_t ]
::operator new( size_t )
; ::operator new( size_t, std::nothrow )
; ::operator new( size_t, ptr )
请看看这篇文章的简要比较。
要点 :完整类型擦除( void*
指针),并且因此没有施工/破坏 ,以字节为单位指定的(通常使用大小sizeof
)。
malloc( size_t )
在所有未初始化的内存(原始内存装着垃圾,总是使用前手动初始化)。 calloc( size_t, size_t )
初始化所有的位为0(少量的开销,但对于POD的数字类型是有用的)。 任何分配的内存应该用发行free
ONLY。
类实例的建筑/销毁应手动完成使用前 / 前释放内存。
要点 :混淆,因为类似的语法做不同的事情, 所有的 delete
-statements调用析构函数, 全部 delete
-statements采取完全类型指针, 一些 new
-statements返回全类型指针, 一些 new
-statements调用一些构造函数。
警告 :你会看到下面, new
可以是一个关键字或功能 。 最好不要谈“新的运营商”和/或“运营商新的”,以避免混乱 。 我称之为“ new
-statements”包含任何有效的语句new
无论是作为一个函数或关键字。 人们也谈“ new
-expressions”,其中new
的关键字,而不是功能。
不要将此自己使用。 这是由新的表达式内部使用(见下文)。
::operator new( size_t )
和::operator new( size_t, std::nothrow )
采取大小的字节数,并返回一个void*
在成功的情况下。 std::bad_alloc
,后者返回NULL
。 ::operator new( sizeof(T) )
为类型的单个对象T
(和delete
发布),和::operator new( n*sizeof(T) )
对多个对象(和delete[]
为释放)。 这些分配没有初始化的内存,尤其是,他们不叫上分配对象的默认构造函数。 因此, 必须初始化所有你使用释放之前手动分配任何元素 delete
或delete[]
注 :我不能强调不够,你不应该使用这个自己。 如果你要使用它,但要确保你传递一个指针void
调用既可以当的,而不是一个类型的指针delete
或delete[]
随时手动初始化后)这种分配。 我亲身经历的运行时错误与非POD类型在某些编译(也许我的错误)。
不要将此自己使用。 这是由新的表达式内部使用(见下文)。 在下文中,我假定void *ptr = ::operator new( n*sizeof(T) )
对于某些类型T
和大小n
。
然后::operator new( n*sizeof(T), (T*) ptr )
初始化n
类型的元素T
从开始ptr
使用默认构造T::T()
没有分配这里,只使用默认的构造函数初始化。
new T( args )
分配和用于类型的单个对象初始化存储器T
使用构造T::T( args )
。 默认构造函数将不会被调用,除非参数被忽略(即new T()
甚至new T
)。 抛出异常std::bad_alloc
失败。 new (std::nothrow) T( args )
不同的是它返回NULL
失败的情况下。 delete
调用析构函数T::~T()
和释放相应的内存。 new T[n]
分配和用于初始化存储器n
类型的对象T
使用默认构造。 抛出异常std::bad_alloc
失败。 new (std::nothrow) T[n]
不同之处在于它返回NULL
在故障的情况下。 delete[]
到调用析构函数T::~T()
的每个元素 ,并释放相应的存储。 这里没有分配。 无论分配是怎么做的:
new (ptr) T(args)
调用构造函数T::T(args)
上存储在存储ptr
。 默认构造函数不被执行,除非被省略参数。 new (ptr) T[n]
调用默认构造T::T()
上n
类型的对象T
从存储ptr
到ptr+n
(即, n*sizeof(T)
个字节)。