sort algorithm compiler error with dynamic array

2020-07-24 03:30发布

I'm having difficulty getting std::begin() to work with a dynamically allocated array (pointer), where it seems to work fine with a stack-allocated one.

This works:

int numbers[100];

// Fill array with numbers

std::sort(std::begin(numbers), std::end(numbers));

This doesn't

int* numbers = new int[10000000];

// Fill array with numbers

std::sort(std::begin(numbers), std::end(numbers));

Here's the resulting error.

ptests.cpp:120:33: error: no matching function for call to ‘begin(int*&)’
     std::sort(std::begin(numbers), std::end(numbers));
                                 ^
ptests.cpp:120:33: note: candidates are:
In file included from /usr/include/c++/4.8/utility:74:0,
                 from /usr/include/c++/4.8/algorithm:60,
                 from ptests.cpp:1:
/usr/include/c++/4.8/initializer_list:89:5: note: template<class _Tp> constexpr const _Tp* std::begin(std::initializer_list<_Tp>)
     begin(initializer_list<_Tp> __ils) noexcept
     ^
/usr/include/c++/4.8/initializer_list:89:5: note:   template argument deduction/substitution failed:
ptests.cpp:120:33: note:   mismatched types ‘std::initializer_list<_Tp>’ and ‘int*’
     std::sort(std::begin(numbers), std::end(numbers));
                                 ^
In file included from /usr/include/c++/4.8/string:51:0,
                 from /usr/include/c++/4.8/random:41,
                 from /usr/include/c++/4.8/bits/stl_algo.h:65,
                 from /usr/include/c++/4.8/algorithm:62,
                 from ptests.cpp:1:
/usr/include/c++/4.8/bits/range_access.h:48:5: note: template<class _Container> decltype (__cont.begin()) std::begin(_Container&)
     begin(_Container& __cont) -> decltype(__cont.begin())

Would it be possible to cast the dynamic pointer to the type begin() expects? Any advice would be appreciated!

标签: c++ c arrays
1条回答
Emotional °昔
2楼-- · 2020-07-24 03:57
std::end(numbers)

This numbers variable is an

int *

That's what it's type is. And there's nothing about this pointer to an integer that tells anyone about how many ints it's pointing to. You allocated it to point to 10000000 ints. But once you've allocated it, all you end up with is a pointer to an int, and nothing more. It is up to your code to keep track of what exactly this pointer is pointing you. You'll wind up exactly with the same pointer if you were to write, simply:

int n;

int *numbers=&n;

This numbers pointer is completely identical to the one you've created. It's just a pointer to an int. Nothing more, nothing less.

std::begin() and std::end() do not work for ordinary pointers, like your pointer to an int here, because, as I've just said, there's nothing about a pointer to some object that indicates how many consecutive objects it's pointing to. It could be one int. It could be two ints. Maybe a million. Or maybe nothing it all, if the pointer is a nullptr.

If you want to sort your dynamically-allocated int array, just pass the beginning and the ending pointer directly:

std::sort(number, numbers+10000000);
查看更多
登录 后发表回答