如何在 C++ 中动态分配数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35532427/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to dynamically allocate arrays in C++
提问by thematroids
I know how to dynamically allocate space for an array in C. It can be done as follows:
我知道如何在 C 中为数组动态分配空间。可以按如下方式完成:
L = (int*)malloc(mid*sizeof(int));
and the memory can be released by:
并且可以通过以下方式释放内存:
free(L);
How do I achieve the equivalent in C++?
我如何在 C++ 中实现等效?
Specifically, how do I use the new
and delete[]
keywords? Especially in the context of creating/destroying a linked list node, or creating and destroying an array whose size is given by a variable during compile time?
具体来说,如何使用new
和delete[]
关键字?尤其是在创建/销毁链表节点,或在编译时创建和销毁其大小由变量给定的数组的上下文中?
回答by Jts
L = new int[mid];
delete[] L;
for arrays (which is what you want) or
对于数组(这是您想要的)或
L = new int;
delete L;
for single elements.
对于单个元素。
But it's more simple to use vector, or use smartpointers, then you don't have to worry about memory management.
但是使用vector更简单,或者使用smartpointers,那么就不用担心内存管理了。
std::vector<int> L(mid);
L.data()
gives you access to the int[]
array buffer and you can L.resize()
the vector later.
L.data()
使您可以访问int[]
数组缓冲区,L.resize()
稍后您可以访问向量。
auto L = std::make_unique<int[]>(mid);
L.get()
gives you a pointer to the int[]
array.
L.get()
给你一个指向int[]
数组的指针。
回答by Martin Gardener
you allocate memory using the new
operator and release a pointer using delete
operator. Note that you can't delete normal variables, only pointers and arrays can be deleted after accomplishing their task.
您使用new
运算符分配内存并使用运算符释放指针delete
。请注意,您不能删除普通变量,只能在完成任务后删除指针和数组。
int * foo;
foo = new int [5];
delete[] foo;
a complete program
一个完整的程序
#include <iostream>
#include <new>
using namespace std;
int main ()
{
int i,n;
int * p;
cout << "How many numbers would you like to type? ";
cin >> i;
p= new (nothrow) int[i];
if (p == nullptr)
cout << "Error: memory could not be allocated";
else
{
for (n=0; n<i; n++)
{
cout << "Enter number: ";
cin >> p[n];
}
cout << "You have entered: ";
for (n=0; n<i; n++)
cout << p[n] << ", ";
delete[] p;
}
return 0;
}
result
结果
How many numbers would you like to type? 5
Enter number : 75
Enter number : 436
Enter number : 1067
Enter number : 8
Enter number : 32
You have entered: 75, 436, 1067, 8, 32,
回答by vikum sri wijesinghe
Following Info will be useful : Source : https://www.learncpp.com/cpp-tutorial/6-9a-dynamically-allocating-arrays/
以下信息将是有用的:来源:https: //www.learncpp.com/cpp-tutorial/6-9a-dynamically-allocating-arrays/
Initializing dynamically allocated arrays
初始化动态分配的数组
If you want to initialize a dynamically allocated array to 0, the syntax is quite simple:
如果要将动态分配的数组初始化为 0,则语法非常简单:
int *array = new int[length]();
Prior to C++11, there was no easy way to initialize a dynamic array to a non-zero value (initializer lists only worked for fixed arrays). This means you had to loop through the array and assign element values explicitly.
在 C++11 之前,没有简单的方法可以将动态数组初始化为非零值(初始化列表仅适用于固定数组)。这意味着您必须遍历数组并显式分配元素值。
int *array = new int[5];
array[0] = 9;
array[1] = 7;
array[2] = 5;
array[3] = 3;
array[4] = 1;
Super annoying!
超级烦人!
However, starting with C++11, it's now possible to initialize dynamic arrays using initializer lists!
但是,从 C++11 开始,现在可以使用初始化列表来初始化动态数组!
int fixedArray[5] = { 9, 7, 5, 3, 1 }; // initialize a fixed array in C++03
int *array = new int[5] { 9, 7, 5, 3, 1 }; // initialize a dynamic array in C++11
Note that this syntax has no operator= between the array length and the initializer list.
请注意,此语法在数组长度和初始值设定项列表之间没有 operator=。
For consistency, in C++11, fixed arrays can also be initialized using uniform initialization:
为了一致性,在 C++11 中,也可以使用统一初始化来初始化固定数组:
int fixedArray[5] { 9, 7, 5, 3, 1 }; // initialize a fixed array in C++11
char fixedArray[14] { "Hello, world!" }; // initialize a fixed array in C++11
One caveat, in C++11 you can not initialize a dynamically allocated char array from a C-style string:
一个警告,在 C++11 中,您不能从 C 样式字符串初始化动态分配的 char 数组:
char *array = new char[14] { "Hello, world!" }; // doesn't work in C++11
If you have a need to do this, dynamically allocate a std::string instead (or allocate your char array and then strcpy the string in).
如果您需要这样做,请改为动态分配 std::string (或分配您的 char 数组,然后将字符串 strcpy 输入)。
Also note that dynamic arrays must be declared with an explicit length:
另请注意,动态数组必须以显式长度声明:
int fixedArray[] {1, 2, 3}; // okay: implicit array size for fixed arrays
int *dynamicArray1 = new int[] {1, 2, 3}; // not okay: implicit size for dynamic arrays
int *dynamicArray2 = new int[3] {1, 2, 3}; // okay: explicit size for dynamic arrays
回答by SKG
In C++ we have the methods to allocate and de-allocate dynamic memory.The variables can be allocated dynamically by using new
operator as,
在 C++ 中,我们有分配和取消分配动态内存的方法。可以使用new
运算符 as动态分配变量,
type_name *variable_name = new type_name;
The arrays are nothing but just the collection of contiguous memory locations, Hence, we can dynamically allocate arrays in C++ as,
数组只不过是连续内存位置的集合,因此,我们可以在 C++ 中动态分配数组,如下所示:
type_name *array_name = new type_name[SIZE];
and you can just use delete
for freeing up the dynamically allocated space, as follows,
for variables,
并且您可以仅delete
用于释放动态分配的空间,如下所示,用于变量,
delete variable_name;
for arrays,
对于数组,
delete[] array_name;
回答by Francis Cugler
You need to be extremely careful when using raw pointers with dynamic memory but here is a simple example.
在动态内存中使用原始指针时需要非常小心,但这里有一个简单的例子。
int main() {
// Normal Pointer To Type
int* pX = nullptr;
pX = new int;
*pX = 3;
std::cout << *pX << std::endl;
// Clean Up Memory
delete pX;
pX = nullptr;
// Pointer To Array
int* pXA = nullptr;
pXA = new int[10]; // 40 Bytes on 32bit - Not Initialized All Values Have Garbage
pXA = new int[10](0); // 40 Bytes on 32bit - All Values Initialized To 0.
// Clean Up Memory To An Array Of Pointers.
delete [] pXA;
pXA = nullptr;
return 0;
} // main
To avoid memory leaks; dangling pointers, deleting memory to early etc. Try using smart pointers. They come in two varieties: shared and unique.
避免内存泄漏;悬空指针,提前删除内存等。尝试使用智能指针。它们有两种:共享的和独特的。
SomeClass.h
某个类.h
#ifndef SOME_CLASS_H
#define SOME_CLASS_H
class SomeClass {
private:
int m_x;
public:
SomeClass();
explicit SomeClass( x = 0 );
void setX( int x );
int getX() const;
private:
SomeClass( const SomeClass& c ); // Not Implemented - Copy Constructor
SomeClass& operator=( const SomeClass& c ); Not Implemented - Overloaded Operator=
}; // SomeClass
#endif // SOME_CLASS_H
SomeClass.cpp
类.cpp
#include "SomeClass.h"
// SomeClass() - Default Constructor
SomeClass::SomeClass() :
m_x( x ) {
} // SomeClass
// SomeClass() - Constructor With Default Parameter
SomeClass::SomeClass( int x ) :
m_x( x ) {
} // SomeClass
// setX()
void SomeClass::setX( int x ) {
m_x = x;
} // setX
// getX()
void SomeClass::getX() const {
return m_x;
} // getX
Old Way Of Using Dynamic Memory
使用动态内存的旧方法
#include <iostream>
#include "SomeClass.h"
int main() {
// Single Dynamic Pointer
SomeClass* pSomeClass = nullptr;
pSomeClass = new SomeClass( 5 );
std::cout << pSomeClass->getX() << std::endl;
delete pSomeClass;
pSomeClass = nullptr;
// Dynamic Array
SomeClass* pSomeClasses = nullptr;
pSomeClasses = new SomeClasses[5](); // Default Constructor Called
for ( int i = 0; i < 5; i++ ) {
pSomeClasses[i]->setX( i * 10 );
std::cout << pSomeSomeClasses[i]->getX() << std::endl;
}
delete[] pSomeClasses;
pSomeClasses = nullptr;
return 0;
} // main
The problem here is knowing when, where and why to delete memory; knowing who is responsible. If you delete the memory to manage it and the user of your code or library assumes you didn't and they delete it there is a problem since the same memory is trying to be deleted twice. If you leave it up to the user to delete it and they assumed you did and they don't you have a problem and there is a memory leak. This is where the use of smart pointers come in handy.
这里的问题是知道何时、何地以及为什么要删除内存;知道谁负责。如果您删除内存来管理它,而您的代码或库的用户认为您没有删除它,则会出现问题,因为同一内存试图被删除两次。如果您将它留给用户删除它并且他们认为您这样做了并且他们没有问题并且存在内存泄漏。这就是智能指针的使用派上用场的地方。
Smart Pointer Version
智能指针版
#include <iostream>
#include <memory>
#include <vector>
#include "SomeClass.h"
int main() {
// SHARED POINTERS
// Shared Pointers Are Used When Different Resources Need To Use The Same Memory Block
// There Are Different Methods To Create And Initialize Shared Pointers
auto sp1 = std::make_shared<SomeClass>( 10 );
std::shared_ptr<SomeClass> sp2( new SomeClass( 15 ) );
std::shared_ptr<SomeClass> sp3;
sp3 = std::make_shared<SomeClass>( 20 );
std::cout << "SP1: " << sp1->getX() << std::endl;
std::cout << "SP2: " << sp2->getX() << std::endl;
std::cout << "SP3: " << sp3->getX() << std::endl;
// Now If you Reach The Return Of Main; These Smart Pointers Will Decrement
// Their Reference Count & When It Reaches 0; Its Destructor Should Be
// Called Freeing All Memory. This Is Safe, But Not Guaranteed. You Can
// Release & Reset The Memory Your Self.
sp1.reset();
sp1 = nullptr;
sp2.reset();
sp2 = nullptr;
sp3.reset();
sp3 = nullptr;
// Need An Array Of Objects In Dynamic Memory?
std::vector<std::shared_ptr<SomeClass>> vSomeClasses;
vSomeClasses.push_back( std::make_shared<SomeClass>( 2 ) );
vSomeClasses.push_back( std::make_shared<SomeClass>( 4 ) );
vSomeClasses.push_back( std::make_shared<SomeClass>( 6 ) );
std::vector<std::shared_ptr<SomeClass>> vSomeClasses2;
vSomeClasses2.push_back( std::shared_ptr<SomeClass>( new SomeClass( 3 ) ) );
vSomeClasses2.push_back( std::shared_ptr<SomeClass>( new SomeClass( 5 ) ) );
vSomeClasses2.push_back( std::shared_ptr<SomeClass>( new SomeClass( 7 ) ) );
// UNIQUE POINTERS
// Unique Pointers Are Used When Only One Resource Has Sole Ownership.
// The Syntax Is The Same For Unique Pointers As For Shared Just Replace
// std::shared_ptr<SomeClass> with std::unique_ptr<SomeClass> &
// replace std::make_shared<SomeClass> with std::make_unique<SomeClass>
// As For Release Memory It Is Basically The Same
// The One Difference With Unique Is That It Has A Release Method Where Shared Does Not.
auto mp1 = std::make_unique<SomeClass>( 3 );
mp1.release();
mp1.reset();
mp1 = nullptr;
// Now You Can Also Do This:
// Create A Unique Pointer To An Array Of 5 Integers
auto p = make_unique<int[]>( 5 );
// Initialize The Array
for ( int i = 0; i < 5; i++ ) {
p[i] = i;
}
return 0;
} // main
Here Are Reference Links To Both Shared & Unique Pointers
这里是共享指针和唯一指针的参考链接
https://msdn.microsoft.com/en-us/library/hh279669.aspx
https://msdn.microsoft.com/en-us/library/hh279669.aspx