How to dynamically allocate arrays in C++

前端 未结 5 750
日久生厌
日久生厌 2020-12-16 06:30

I know how to dynamically allocate space for an array in C. It can be done as follows:

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

and the memory c

5条回答
  •  甜味超标
    2020-12-16 06:53

    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

    #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
    

    Old Way Of Using Dynamic Memory

    #include 
    #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 
    #include 
    #include 
    #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( 10 );
    
        std::shared_ptr sp2( new SomeClass( 15 ) );
    
        std::shared_ptr sp3;
        sp3 = std::make_shared( 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> vSomeClasses;
        vSomeClasses.push_back( std::make_shared( 2 ) );
        vSomeClasses.push_back( std::make_shared( 4 ) );
        vSomeClasses.push_back( std::make_shared( 6 ) );
    
        std::vector> vSomeClasses2;    
        vSomeClasses2.push_back( std::shared_ptr( new SomeClass( 3 ) ) );
        vSomeClasses2.push_back( std::shared_ptr( new SomeClass( 5 ) ) );
        vSomeClasses2.push_back( std::shared_ptr( 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 with std::unique_ptr &
        // replace std::make_shared with std::make_unique
        // 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( 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( 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/hh279676.aspx

提交回复
热议问题