可变大小的对象可能无法在C++中进行初始化。

18

我知道这个问题之前被问过,但我不明白为什么在我的情况下它不起作用。

void calc(vector<char> zodis1, vector<char> zodis2, vector<char> zodisAts,int zo1,int zo2,int zoA)
{
   int i,u=0;

   int zod1[zo1]=0;
   int zod2[zo2]=0;
   int zodA[zoA]=0; 
}

zod1、zod2和zoA都会给我报错:variable-sized object may not be initialized c++,但编译器在初始化之前应该知道zo的含义,因为cout<<zo1;可以工作并输出其含义。

问题出在哪里?


2
需要明确的是:在标准C++中,“int zod1 [zo1];”是不被允许的。然而,许多编译器提供了这个扩展功能。根据您的编译器错误信息,它有一个扩展功能可以允许“int zod1 [zo1];”,但不允许提供“=0;”。 - M.M
2个回答

26

在编译时,只能使用常量大小来声明array。而变量zo1zo2zoA的值只有在运行时才能知道。

更具体地说,当您在堆栈上分配内存时,必须在编译时知道其大小。由于数组是局部于方法的,它们将被放置在堆栈上。您可以使用常量值,或使用new在堆上分配内存,并在完成后使用delete释放内存,如下:

int* zod1 = new int[zo1];
//.... other code


delete[] zod1;

但你也可以使用vector来代替array,而且vector会负责在堆上分配内存。

顺便提一下,你不应该通过值传递vector,因为整个向量将被复制并作为参数传递,调用者那边看不到任何变化。相反,使用 vector<char>& zodis1


2
具体来说,变量可以随时更改值,但文件需要知道要分配多少内存。关于向量的侧面说明:这被称为“指针”,本质上不是复制可能大量的内存,而是“指向”数据;这样更有效率。 - lewisjb
1
@user3102621,当分配在堆上而不是栈上时,您可以这样做。 - Rakib
感谢您的回答。在向量方面,我想那可能会更好,但我不会对向量进行任何更改,所以没有必要这样做(除非我认为这可以节省内存?) - user3102621
@user3102621,如果您不需要更改,则将其发送为常量 const vector<char>& - Rakib
@Rakib,那不完全准确。我可以声明一个具有可变大小的数组,只是我不能初始化它。当然,汇编看起来很丑陋,但显然编译器有一种方法在运行时确定数组的大小。初始化很棘手,因为没有办法在编译时知道您是否通过写入堆栈中不应该写入的地址来引入错误。另请参见:为什么不允许使用const初始化可变大小的对象 - mihai
显示剩余3条评论

0

这里是修复方法,你可以写下面的代码替换掉出错的那一行;

备选方案1 你可以使用向量:

vector<int> zod1(zo1, 0);

方案二(例如,由于我们知道“0 <= s.length <= 100”,因此可以使用常量值):

int zod1[100] = { 0 };

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接