Is it possible to dynamically create an array of constant size in C++?

后端 未结 4 1081

First of all, I want to reassure you all that I am asking this question out of curiosity. I mean, don\'t tell me that if I need this then my design has problems because I do

相关标签:
4条回答
  • 2020-12-06 05:27

    You just do

    int *p = new unsigned int [3]
    

    You can then use *p as a pointer or an array i.e. *(p+1) or p[1]

    0 讨论(0)
  • 2020-12-06 05:31

    To get a pointer to an array from new, you have to dynamically allocate a two-dimensional array:

    int (*p)[3] = new int[1][3];
    
    0 讨论(0)
  • 2020-12-06 05:44

    The reason you can't do it is that new int[3] already allocates exactly what you want, an object of type int[3]. It's just that what the new-expression returns, is a pointer to its first element. 5.3.4/1:

    If the entity is a non-array object, the new-expression returns a pointer to the object created. If it is an array, the new-expression returns a pointer to the initial element of the array.

    Returning a pointer to the first element is what allows the 3 to be unknown until runtime, so I suppose that by knowing it in advance, you've tripped over flexibility that you aren't using.

    I guess the ways around this are to reinterpret_cast back to the pointer type you want (not necessarily portable), or to allocate a struct containing an int[3] (and use a pointer to its data member).

    [Edit: er, yeah, or FredOverflow's idea, which has neither disadvantage, but requires use of delete[] instead of delete.]

    I guess the moral is, if you write templates that naively allocate some unknown type T with new, then the template won't work when someone passes an array type as T. You'll be assigning it to the wrong pointer type, and if you fix that (perhaps with auto), you'll be deleting it wrongly.

    Edit in answer to j_kubik's question:

    Here's one way to distinguish between array and non-array types. If you write a function like this, that returns an object that holds the pointer and is capable of correctly deleting it, then you have a generic new/delete for any type T.

    #include <iostream>
    
    template <typename T>
    void make_thing_helper(T *) {
        std::cout << "plain version\n";
    }
    
    template <typename T, int N>
    void make_thing_helper(T (*)[N]) {
        std::cout << "array version\n";
    }
    
    template <typename T>
    void make_thing() {
        make_thing_helper((T*)0);
    }
    
    int main() {
        typedef int T1;
        typedef int T2[3];
        make_thing<T1>();
        make_thing<T2>();
    }
    
    0 讨论(0)
  • 2020-12-06 05:50

    You could always use boost::array, which will be in C++0x. Otherwise, any solution will be awkward at best: arrays are broken in C, and C++ maintains compatilibity with C in this respect. Fred Overflow offered one solution; even easier (but syntactically noisy) would be to wrap the array in a struct: struct A { int arr[3]; }; and allocate and manipulate this.

    0 讨论(0)
提交回复
热议问题