C++如何在用new创建动态数组的同时初始化数组

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++如何在用new创建动态数组的同时初始化数组相关的知识,希望对你有一定的参考价值。

new命令是C++的专用命令,用来动态分配内存空间。 相当于C语言中的malloc()函数功能。
用new创建动态数组的应用过程:
1、定义指针变量
2、获得数组长度
3、用new分配相应的内存空间
4、使用动态数组
5、不再使用该内存时,释放指针,相应命令为:delete
参考代码:

#include<iostream>using namespace std; int main() int *parr=NULL; int num=0; cout << "input num: " ; cin >> num ; parr=new int[num]; //分配一个具有num个int元素的数组空间 for( int i=0;i<num;i++ ) parr[i]=i*i ; for( int j=0;j<num;j++ ) cout << parr[j] <<" "; cout<<endl; delete []parr; //释放数组,注意[] return 0;
参考技术A 一般来说开辟一个空间并且赋值是 int *p = new int(4); 即 *p = 4。
开辟10个空间数组是 int *p = new int[10]; (int *p = new int[10](4) 是不对的,不支持)
但是想在开辟空间的同时并且初始化的话可以这样写

1/ int *p = new int[10] 或者 int *p = new int[10]() 这两种都是初始化为0
2/ int *p = new int[10]1,2,3,4,5,6,7,8,9,10 这种是直接赋值,但是数组太长的话还是的用for去赋值
3/ int* p = new int[10] 1 ; 这种赋值的结果是 1,0,0,0,0,0,0,0,0,0

如何在 C++ 中动态分配数组

【中文标题】如何在 C++ 中动态分配数组【英文标题】:How to dynamically allocate arrays in C++ 【发布时间】:2016-02-21 04:44:49 【问题描述】:

我知道如何在C中为数组动态分配空间。可以这样做:

L = (int*)malloc(mid*sizeof(int)); 

内存可以通过以下方式释放:

free(L);

如何在 C++ 中实现等效?

具体来说,如何使用newdelete[] 关键字?尤其是在创建/销毁链表节点,或创建和销毁其大小由编译时变量给出的数组的上下文中?

【问题讨论】:

我强烈建议您查看 C++ 参考的索引(或目录)以查找“新”或“新运算符”或“动态内存”。任何好的参考资料都应该说明如何分配和释放内存。 这里有大量的*** Articles on memory allocation for C++。 对于懒惰搜索,我使用了Google for c++ dynamic memory example。 【参考方案1】:
int* L = new int[mid]; 
delete[] L;

对于数组(这是你想要的)或

int* L = new int;   
delete L;

对于单个元素。

但是使用vector,或者使用smartpointers更简单,那就不用担心内存管理了。

std::vector<int> L(mid);

L.data() 让您可以访问int[] 数组缓冲区,您可以稍后通过L.resize() 向量。

auto L = std::make_unique<int[]>(mid);

L.get() 给你一个指向int[] 数组的指针。

【讨论】:

【参考方案2】:

以下信息将很有用: 来源:https://www.learncpp.com/cpp-tutorial/6-9a-dynamically-allocating-arrays/

初始化动态分配的数组

如果要将动态分配的数组初始化为0,语法很简单:

int *array = new int[length]();

在 C++11 之前,没有简单的方法将动态数组初始化为非零值(初始化列表仅适用于固定数组)。这意味着您必须循环遍历数组并显式分配元素值。

int *array = new int[5];
array[0] = 9;
array[1] = 7;
array[2] = 5;
array[3] = 3;
array[4] = 1;

超级烦人!

不过,从 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

请注意,此语法在数组长度和初始化列表之间没有 operator=。

为了一致性,在 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

需要注意的是,在 C++11 中,您不能从 C 风格的字符串初始化动态分配的 char 数组:

char *array = new char[14]  "Hello, world!" ; // doesn't work in C++11

如果您需要这样做,请改为动态分配 std::string(或分配您的 char 数组,然后将字符串 strcpy 放入)。

还要注意动态数组必须用明确的长度声明:

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

【讨论】:

【参考方案3】:

您使用new 运算符分配内存并使用delete 运算符释放指针。注意不能删除普通变量,只有指针和数组完成任务后才能删除。

int * foo;
foo = new int [5];
delete[] foo;

一个完整的程序

#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;

结果

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,

【讨论】:

【参考方案4】:

在 C++ 中,我们有分配和取消分配动态内存的方法。变量可以通过使用new 运算符 as 来动态分配,

                     type_name *variable_name = new type_name;

数组只不过是连续内存位置的集合,因此,我们可以在 C++ 中动态分配数组,

                     type_name *array_name = new type_name[SIZE];

您可以使用delete 来释放动态分配的空间,如下所示, 对于变量,

                     delete variable_name;

对于数组,

                     delete[] array_name;

【讨论】:

【参考方案5】:

在动态内存中使用原始指针时需要非常小心,但这里有一个简单的示例。

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

为了避免内存泄漏;悬空指针,提前删除内存等。尝试使用智能指针。它们有两种类型:共享的和独特的。

SomeClass.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

#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

使用动态内存的旧方法

#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

这里的问题是知道何时、何地以及为什么要删除内存;知道谁负责。如果您删除内存来管理它,而您的代码或库的用户认为您没有删除它,那么就会出现问题,因为同一块内存正试图被删除两次。如果您将其留给用户删除它并且他们认为您这样做了并且他们没有您有问题并且存在内存泄漏。这就是使用智能指针派上用场的地方。

智能指针版本

#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

这里是共享指针和唯一指针的参考链接

https://msdn.microsoft.com/en-us/library/hh279669.aspx

https://msdn.microsoft.com/en-us/library/hh279676.aspx

【讨论】:

以上是关于C++如何在用new创建动态数组的同时初始化数组的主要内容,如果未能解决你的问题,请参考以下文章

如何初始化动态对象数组

怎么使用new操作符创建动态数组?

如何在C++中创建一维动态数组

如何在 C++ 中动态分配数组

C++如何用new动态开辟一个一维字符数组

如何在 C++ 中初始化指向动态二维数组的指针 [关闭]