我该怎么做才能获得“动态”数组的大小?

时间:2014-09-10 01:42:14

标签: c++ arrays pointers sizeof

我有这个代码。

   int x[5];
   printf("%d\n",sizeof(x) );


   int *a;
   a = new int[3];
   printf("%d\n",sizeof(*a));

当我将'static'数组传递给sizeof()时,它返回声明的数组的维度乘以数据类型在内存中使用的字节数。但是,动态数组似乎不同。我的问题是我应该怎么做才能获得“动态”数组的大小?

PD:它可能与以下内容有关吗?

int *a;
a=new int[3];
a[0]=3;
a[1]=4;
a[2]=5;
a[3]=6;

如果假设我在“a = new int [3]”中设置了“限制”,为什么我可以修改第三个位置。

3 个答案:

答案 0 :(得分:3)

  

当我将'static'数组传递给sizeof()时,它返回声明的数组的维度乘以数据类型在内存中使用的字节数。

正确,就是如何计算整个数组的大小。

  

然而,动态数组似乎有所不同。

这是因为你没有传递动态数组;你正在传递指针。指针是一种数据类型,其大小与它可能指向的内存块大小无关,因此您始终可以获得一个常量值。为动态大小的内存块分配内存时,需要存储分配大小以供将来参考:

size_t count = 123; // <<== You can compute this count dynamically
int *array = new int[count];
cout << "Array size: " << (sizeof(*array) * count) << endl;

C ++ 14将具有可变长度数组。当您选中sizeof时,这些数组将提供适当的大小。

  

它可能与以下内容有关吗? [...]

不,这是无关的。您的代码段显示未定义的行为(写入已分配的内存块的末尾),这意味着您的代码无效。它可能会立即崩溃,导致以后崩溃,或表现出其他任意行为。

答案 1 :(得分:1)

在C ++数组中,运行时没有任何内在大小。

编译时,可以使用sizeof显示,以获得编译器已知的大小,但如果实际大小直到运行时才知道那么它是责任跟踪长度的程序。

两种流行的策略是:

  • 保留一个包含数组当前长度的单独变量。
  • 在数组的末尾添加一个额外的元素,该元素包含某种标记值,表示它是最后一个元素。例如,如果您的数组仅为正整数,那么您可以使用-1作为标记。

如果你没有跟踪数组的结尾并且你写的超出你分配的内容那么你就有可能覆盖存储器中存储在数组旁边的其他数据,这可能会导致崩溃或其他未定义的行为。

其他语言倾向于使用前一种策略,并提供获取当前长度记录的机制。有些语言也允许在创建数组后动态调整其大小,这通常涉及创建一个新数组并在销毁原始数据之前复制所有数据。

标准库中的vector类型提供了对数组的抽象,当在运行时之前不知道数据的大小时,这可以更方便。它跟踪当前的数组大小,并允许数组稍后增长。例如:

#include <vector>

int main() {
    std::vector<int> a;
    a.push_back(3);
    a.push_back(4);
    a.push_back(5);
    a.push_back(6);
    printf("%d\n", a.size());

    return 0;
}

作为旁注,由于a.size()(和sizeof(...))返回size_t,其大小不一定与int相同(尽管它发生了要在某些平台上使用printf%d一起使用是不可移植的。相反,可以使用iostream,这也是更惯用的C ++:

#include <iostream>

std::cout << a.size() << '\n';

答案 2 :(得分:0)

你没有,至少在标准C ++中没有。你必须自己跟踪它,使用std :: vector等原始指针的替代方法来跟踪分配的大小,或者在Microsoft上使用非标准函数,如_msize(http://msdn.microsoft.com/en-us/library/z2s077bc%28v=vs.80%29.aspx) MacOS X上的Windows或malloc_size(https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/malloc_size.3.html)。