3

我得到了一个带有以下声明的标题:

//The index of 1 is used to make sure this is an array.
MyObject objs[1];

但是,我需要使这个数组在程序启动时动态调整大小。我认为我应该将它声明为 MyObject *objs;,但我认为如果原来的程序员这样声明,那是有原因的。

无论如何我可以动态调整它的大小吗?还是我应该将其更改为指针然后 malloc() ?

我可以以某种方式使用一些新的关键字来做到这一点吗?

4

8 回答 8

16

使用STL 向量

#include <vector>

std::vector<MyObject> objs(size);

向量是一个动态数组,是标准模板库的一部分。当您将对象推回数组时,它会自动调整大小,并且可以像使用[]operator的普通 C 数组一样访问。此外,如果容器不为空,&objs[0]则保证指向内存中的连续序列(与列表不同)。

于 2009-04-07T22:02:00.660 回答
6

你是对的。如果要动态实例化其大小,则需要使用指针。

(既然您使用的是 C++,为什么不使用new运算符而不是malloc?)

MyObject* objs = new MyObject[size];
于 2009-04-07T22:03:12.827 回答
3

还是我应该将其更改为指针然后 malloc() ?

如果这样做,将如何为 malloc 内存中的对象调用构造函数?我会给你一个提示 - 他们不会 - 你需要使用 std::vector。

于 2009-04-07T22:40:50.660 回答
1

我只看到一个数组用作结构或联合中的指针。这是很久以前的事,用于将字符串的 len 和 first char 视为哈希,以提高脚本语言的字符串比较速度。

代码与此类似:

union small_string {
   struct {
      char len;
      char buff[1];
   };
   short hash;
};

然后使用 malloc 初始化 small_string,注意 c 转换实际上是 reinterpret_cast

small_string str = (small_string) malloc(len + 1);
strcpy(str.buff, val);

并测试平等

int fast_str_equal(small_string str1, small_string str2)
{
   if (str1.hash == str2.hash)
      return strcmp(str1.buff, str2.buff) == 0;
   return 0;
}

如您所见,这不是一种非常便携或安全的 c++ 风格。但是为由短字符串索引的关联数组提供了极大的速度改进,这是大多数脚本语言的基础。

我今天可能会避免这种风格的 c++。

于 2009-04-08T10:58:14.820 回答
1

这是在某个结构的末尾吗?

我见过的一个技巧是声明一个结构

struct foo {
/* optional stuff here */
int arr[1];
}

并且 malloc 比sizeof (struct foo)这样更多的内存arr成为一个可变大小的数组。

当我在破解 C 时,这在 C 程序中相当普遍,因为可变大小的数组不可用,并且进行额外的分配被认为太容易出错。

在几乎所有情况下,正确的做法是将数组更改为 STL 向量。

于 2009-04-08T19:30:30.640 回答
0

如果您想要一个动态调整大小的数组,最好使用 STL,有几个选项,一个是std::vector。如果您不介意插入,也可以使用 std::list。

于 2009-04-07T22:02:08.103 回答
0

它似乎 - 是的,你可以做这个改变。
但是在 sizeof( objs ); 上检查你的代码;

MyObj *arr1 = new MyObj[1];
MyObj arr2[1];

sizeof(arr1) != sizeof(arr2)

也许这个事实在您的代码中的某个地方使用过。

于 2009-04-07T22:27:20.443 回答
0

那个评论非常糟糕。即使注释另有说明,单元素数组也是数组。

我从未见过有人试图以这种方式强制执行“是一个数组”。数组语法很大程度上是语法糖(a[2]给出的结果与2[a]: 中的第三个元素相同a注意 这是一种有趣且有效的语法,但通常使用起来非常糟糕,因为你会无缘无故地混淆程序员)) .

因为数组语法在很大程度上是语法糖,所以切换到指针也很有意义。但是,如果您要这样做,那么使用 withnew[]更有意义(因为您可以免费调用构造函数),并且使用 withstd::vector更有意义(因为您不必记住调用delete[]数组所在的每个位置由于返回、中断、语句结束、抛出异常等而超出范围)。

于 2009-04-08T00:19:19.253 回答