您可以在C ++中使用'new'模拟动态数组大小吗?

问题描述 投票:3回答:3

[我知道您可以使用malloc创建一个动态大小的数组,但是我对使用new做同样的事情感兴趣,部分原因是malloc在C ++中被认为是不好的做法,并且出于好奇心。

说我正在编写一个程序,该程序将接收的输入字节可能多达MAX_INPUT_SIZE,该字节太大,以至于分配该大小的数组可能会阻止其他程序在同一程序上运行的能力内存。但是,所有输入大小[0, MAX_INPUT_SIZE]都可能相等。有没有一种方法可以编写程序,使得堆上的内存分配与输入大小成比例,因此除非收到足够大的输入,否则其他程序的性能不会受到影响?假设这些限制:

  • 无法使用malloc
  • 不能使用vector或其他包装器(假设我们正在寻求极快的性能)
  • 解释数据的算法必须将所有数据都放在一个数组中(出于性能考虑,这样小输入仍然会非常快地处理)
  • 程序应分配大约等于输入大小的内存

这些限制是不切实际的严格限制,但这只是假设。这是一个潜在的解决方案:

char *data;
long long int data_size;
/* receive input size */

if( data_size <= 1000 )
    data = new char[1000];

else if( data_size <= 10000 )
    data = new char[10000];
...
else if( data_size <= MAX_INPUT_SIZE / 10 )
    data = new char[MAX_INPUT_SIZE / 10];

else if( data_size <= MAX_INPUT_SIZE )
    data = new char[MAX_INPUT_SIZE];

我的问题是,上面的代码实际上只在运行其代码行时才分配new内存,还是为所有这些new调用准备内存,而只是将指针分配给所请求的那个?

基本上,此程序是否可以在MAX_INPUT_SIZE超出可用RAM的计算机上运行,​​但实际的data_size不会?

如果答案是肯定的,它将运行,那么为什么new强制您具有在编译时可解析的数组大小?当然,C ++编译器是否有可能使new动态分配呢?如果是这样,那么这仅仅是设计选择,并且不允许动态数组大小分配的原因是什么?

如果答案为“否”,则它将无法运行,是否存在受限制的替代解决方案?

c++ arrays dynamic-memory-allocation large-data
3个回答
4
投票

上述代码实际上只在运行代码行时才分配new内存,还是为所有这些new调用准备了内存,而只是将指针分配给了所请求的那个?

直到在运行时实际调用new才分配内存。

基本上,此程序是否可以在MAX_INPUT_SIZE超出可用RAM的计算机上运行,​​但实际的data_size不会?

为什么new强制您具有在编译时可解析的数组大小?

不是。你从哪儿得到这个主意的?仅静态数组需在编译时指定其大小。 动态数组不。使用new[]的主要好处之一是可以为其提供一个直到运行时才知道的值。例如:

char *data;
long long int data_size;
/* receive input size */

data = new char[data_size];

1
投票

我相信您在new分配中混合了数组声明。

带数组:

#define this_has_to_be_compile_time_constant  50
// or: const int this_has_to_be_compile_time_constant = 50;
char array[this_has_to_be_compile_time_constant];

但是有新的:

int this_can_be_a_variable = some_function();
char *array = new char[this_can_be_a_variable];

0
投票
  • 不能使用矢量或其他包装(例如,我们正在寻找极快的性能)

只需使用向量。

以下代码段来自运行代码。

  • 游戏板对象的大小在编译时未知。

  • 在我的实践中,游戏板被创建为空,这完全不需要时间。

    //创建游戏板-带有细胞向量

    CellVec_t gameBoard;

因此,确定大小后,只有一行执行分配工作。选项包括默认值,cmd行覆盖,显示最大大小等。

来自en.cppreference.com/w/cpp/container/vector:

“就性能而言,重新分配通常是昂贵的操作。reserve()函数可用于消除重新分配,如果元素是事先已知的。

因此

gameBoard.reserve (static_cast<long unsigned int>(aMaxRow * aMaxCol));

GOLUtil_t  gBrd(aMaxRow, aMaxCol, gameBoard, *ansiTerm);

...
© www.soinside.com 2019 - 2024. All rights reserved.