我想声明一个if语句内的数组。我这样编写我的代码,以便在if-block退出时对象保持在范围内,但现在我有一个新问题:“获取临时数组的地址”。我怎样才能以另一种方式重写这个,以使maskArray被赋予正确的值?C + +错误:“临时阵列的地址”
int* maskArray;
if(conditional==true)
maskArray = (int[9]) {0,1,0,1,-4,1,0,1,0};
我想声明一个if语句内的数组。我这样编写我的代码,以便在if-block退出时对象保持在范围内,但现在我有一个新问题:“获取临时数组的地址”。我怎样才能以另一种方式重写这个,以使maskArray被赋予正确的值?C + +错误:“临时阵列的地址”
int* maskArray;
if(conditional==true)
maskArray = (int[9]) {0,1,0,1,-4,1,0,1,0};
您可以使用一个临时数组来实现这一
int temp [] = {0,1,0,1,-4,1,0,1,0};
size_t n = sizeof(temp)/sizeof(int);
if (condition == true)
{
maskArray = new int[n]{0,1,0,1,-4,1,0,1,0};
}
// ...
delete [] maskArray; // Free memory after use
或者干脆使用std::vector
std::vector<int> maskArray;
if(condition == true)
{
maskArray = {0,1,0,1,-4,1,0,1,0}; // C++11 initializer_list vector assignment
}
(int[9]) {0,1,0,1,-4,1,0,1,0}
创建一个临时数组,将尽快销毁了声明全文完成了。 (请注意,这在技术上不是C++,而是编译器在C++中支持的C99功能。)
maskArray = (int[9]) {0,1,0,1,-4,1,0,1,0};
将临时数组转换为指针并将该指针存储在maskArray
中。只要此语句完成,临时数组将被销毁,并且maskArray
中的值将不再有效。
这是可以接受使用这种临时数组的唯一方法是通过将其传递到将使用它的功能,使用它在同样的语句,如:
void foo(int (&arr)[9]);
foo((int[9]) {0,1,0,1,-4,1,0,1,0});
这是正常的,因为即使尽管临时数组被销毁,但它只在函数返回后才被销毁,并且没有任何数组正在使用。 (和功能最好不要长期引用或指针以某种方式保存到数组,但随后这是没有异于常人。)
在C中,复合文字持续封闭范围的持续时间。在OP的代码中,它是完整的陈述 - 但仅仅是因为在该范围内只有一个陈述。 –
GNU C++扩展将复合文字与C99区别对待。 GNU C++版本具有比C99版本更短的生命周期,单一表达VS自动化。 – user3528438
@ user3528438所以你说在GNU C++中,int * p =(int []){1,2,3};'创建一个悬挂指针?神奇的延伸... –
if (...)
{
static int a[9] = { ... };
maskArray = a;
}
请提供一些关于你的答案的更多细节 – silwar
@silwar当然,OP应该得到一本关于C++的好书,并阅读对象生命周期。或者只是使用网络搜索。 –
假设你不打算稍后修改什么maskArray
点,然后最好/最简单的解决方法是:
const int* maskArray;
if(conditional==true)
{
static const int myArray[9] = {0,1,0,1,-4,1,0,1,0};
maskArray = &myArray[0];
}
静态常量工作,如果你不打算更新数组,但如果你要更新它,你需要一个独立的副本。这可以在堆栈上或堆上创建。在栈上创建:
int* maskArray;
int myArray[9] = {0,1,0,1,-4,1,0,1,0};
if(conditional==true)
{
maskArray = &myArray[0];
}
// when `myArray` goes out of scope, the pointer stored in maskArray will be useless! If a longer lifetime is needed, use the heap (see below).
要动态地在堆上创建数组的新副本,您需要分配使用new[]
内存。这样做的好处是,只要它在您决定删除它之前有用,它就可以保留。
int* maskArray;
if(conditional==true)
{
maskArray = new int[9] {0,1,0,1,-4,1,0,1,0};
}
记得要删除以后使用delete[] maskArray
!
您只能在声明数组时初始化它。因此,如果需要在一个循环中先限定申报循环内的数组:
int* maskArray;
if(conditional==true) {
int locArray[] = {0,1,0,1,-4,1,0,1,0};
maskArray = locArray;
...
} // locArray goes out of scope here
// BEWARE : maskArray is now a dangling pointer (maskArray = NULL is safer)
由于注意到了MM,你可以通过声明它的块中,(或者,如果你能忽略它避免晃来晃去maskArray
直接使用locArray
):
if(conditional==true) {
int locArray[] = {0,1,0,1,-4,1,0,1,0};
int *maskArray = locArray; // may be fully omitted if locArray is enough
你的意思是有一个'{'某处? –
'maskArray'应该在条件内声明,以避免悬挂指针的可能性。 '如果'不是一个循环。 –
@ M.M感谢缺少的'{'...对于指针,我不知道OP为什么将它写出if块,这就是为什么我把它留在外面的原因。但是它可以在循环内部声明('int * maskArray = locArray;'),或者如果使用'locArray'就足够了,甚至不会声明。 –
'(INT [9]){0,1,0,1,-4,1,0,1,0};'是C构建体,它是不合法的C++。请确认您尝试使用哪种语言 –
这实际上是C中从“复合文字”中借用的C++扩展。在C中,这是有效的代码,因为临时文件具有自动存储持续时间。在C++中,通常不是,至少该扩展的GCC版本不是,因为临时表达式具有单个表达式生存期。 – user3528438