我读到了用C ++获取数组的长度,你这样做:
int arr[17];
int arrSize = sizeof(arr) / sizeof(int);
我试着为字符串做同样的事情: 我在哪里
string * arr;
arr = new (nothrow) string [213561];
然后我做
arr[k] = "stuff";
我遍历每个索引并将“stuff”放入其中。
现在我想要数组的大小应该是213561,这是正确的方法,为什么它在C ++中如此复杂?
答案 0 :(得分:8)
您尝试做的事情无法正常工作,因为sizeof在编译时适用于类型(并且指针类型永远不会占用它们可能指向的数组的大小)。
在您的情况下,计算sizeof(arr)返回指针在内存中占用的大小,而不是
size of the array * size of a std::string
我建议你使用这两个选项中的一个
......除非你有充分理由不这样做。
答案 1 :(得分:6)
在C ++中执行此操作的正确方法是使用vector
。这样,您既可以预先指定大小,也可以随时调整大小。
预先指定尺寸:
using namespace std;
vector<string> arr(213561);
for (vector<string>::iterator p = arr.begin(); p != arr.end(); ++p)
{
*p = "abc";
}
随时展开向量:
using namespace std;
vector<string> arr; // <-- note, default constructor
for (int i = 0; i < 213561; ++i)
{
// add elements to the end of the array, automatically reallocating memory if necessary
arr.push_back("abc");
}
无论哪种方式,都可以找到数组的大小:
size_t elements = arr.size(); // = 213561
答案 2 :(得分:1)
sizeof
方法只有在您的数组实际上是数组时才有效,即具有数组类型的对象。在您的第一个示例中,对象arr
的类型为int[17]
。它是一种数组类型,这意味着您可以使用sizeof
方法并获得17
作为结果。
将数组类型T[N]
转换为指针类型T *
后,基本上会丢失数组类型。应用于指针的sizeof
方法不会计算为原始数组的大小。
当您使用T[N]
分配类型为new[]
的数组时,结果会立即显示类型为T *
的指针。它从一开始就不是数组类型。有关数组大小的信息会立即丢失,尝试使用带有此类指针的sizeof
方法将无法正常工作。为了保留有关动态分配的运行时大小数组的大小信息,您必须自己将其存储在单独的变量中。
答案 3 :(得分:1)
以下是查找数组大小的方法:
const size_t ARRAY_SIZE = 17;
int array[ARRAY_SIZE];
//...
std::cout << "My array size is: " << ARRAY_SIZE << "\n";
您可以将ARRAY_SIZE
放入标题中,以便其他翻译单元可以访问数组大小。
如果您想要一个根据需要增长的动态数组,请尝试std::vector
。
答案 4 :(得分:0)
您需要使用单独的变量跟踪长度。没有办法得到你只有指针的区域的长度,除非你把它存储在某个地方。
答案 5 :(得分:0)
您无法获得已分配数组的长度。 您可以做的是在分配时单独保存..
另外,你可以使用strlen()检查字符串的长度(这不是你要求的,但仍然是......)
答案 6 :(得分:0)
在c ++中,arr
只是对数组第一个元素的引用。如果是动态数组,则无法实现。
答案 7 :(得分:0)
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 ++无法告诉你如果动态分配数组有多大的主要原因 - 它不知道大小,所有它都是指向已分配内存的指针。 / p>
#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;
}