В C и C++ есть тонкий нюанс с распределением памяти. Ни один из языков не поддерживает динамические массивы. Вот то, что вы видите:
int ary[17];
int arrSize = sizeof(ary)/sizeof(ary[0]);
Здесь ary
настоящий массив из 17 целых чисел. Расчет размера массива работает, потому что sizeof(ary)
возвращает размер блока памяти, выделенного для всего массива. Вы делите это по размеру каждого элемента и violà у вас есть количество элементов в массиве.
std::string * arr;
arr = new (std::nothrow) std::string[213561];
В этом случае arr
является указателем на какую-то память. Оператор new
выделяет блок памяти, достаточно большой для хранения 213 561 смежных объектов std::string
и создает каждый из них в памяти. Переменная arr
просто указывает на начало блока памяти. C++ не отслеживает количество выделенных элементов. Вы действительно не создали динамический массив - вместо этого вы выделили достаточно памяти для связки смежных объектов.
C и C++ оба позволяют применять оператор подписи к указателю как синтаксический сахар. Вы увидите много комментариев о том, как arr[0]
переводит *(arr + 0)
. Реальность заключается в том, что выделение памяти с использованием оператора new
приводит к блоку памяти, который не является массивом вообще. Синтаксический сахар делает его похожим на одно. Следующее, что вы столкнетесь, это то, что многомерные массивы похожи на сахар.
Рассмотрите следующий фрагмент.Как только вы поймете, что там происходит, вы будете намного ближе к пониманию того, как работает память. Это основная причина, по которой C и C++ не могут сказать вам, насколько велик массив, если он динамически распределен. он не знает размер, все, что у него есть, является указателем на выделенную память.
#include <iostream>
int
main()
{
//
// The compiler translates array subscript notation into
// pointer arithmetic in simple cases so "hello"[3] is
// is translated into *("hello" + 3). Since addition is
// commutative, the order of "hello" and 3 are irrelevant.
//
std::cout
<< "\"hello\"[3] = '" << "hello"[3] << "'\n"
<< "3[\"hello\"] = " << 3["hello"] << "\n"
<< std::endl;
//
// All memory is linear in C or C++. So an 3x3 array of
// integers is a contiguous block of 9 integers in row
// major order. The following snippet prints out the 3x3
// identity matrix using row and column syntax.
//
int ary[3][3] = { { 1, 0, 0 },
{ 0, 1, 0 },
{ 0, 0, 1 } };
for (int r=0; r<3; ++r) {
for (int c=0; c<3; ++c) {
std::cout << "\t" << ary[r][c];
}
std::cout << "\n";
}
std::cout << "\n";
//
// Since memory is linear, we can also access the same
// 3x3 array linearly through a pointer. The inner loop
// is what the compiler is doing when you access ary[r][c]
// above - "ary[r][c]" becomes "*(ptr + (r * 3) + c)"
// since the compiler knows the dimensions of "ary" at
// compile time.
//
int *ptr = &ary[0][0];
for (int i=0; i<9; ++i) {
ptr[i] = i;
}
for (int r=0; r<3; ++r) {
for (int c=0; c<3; ++c) {
std::cout << "\t" << *(ptr + (r * 3) + c);
}
std::cout << "\n";
}
return 0;
}
Это не «так сложно» - вы не можете делать то, что вы просите в C. – 2009-12-25 16:05:32
У вас есть фон, в котором язык программирования? – Partial
Я не понимаю, размер массива - это исходный номер, который вы использовали для его создания. Просто определите его как именованную константу и обратитесь к константе. Что касается знания количества элементов в массиве, вам придется отслеживать это. В противном случае используйте 'std :: vector'. –