C++-关于动态数组的范围
C++ - Regarding the scope of dynamic arrays
我有一个关于动态数组范围的快速问题,我认为这会导致我正在编写的程序中出现错误。这个代码段检查一个函数参数,并根据用户传递的内容分支到第一个或第二个。
然而,当我运行程序时,我得到了一个与范围相关的错误:
错误:未在此作用域中声明"Array"
除非我对C++的了解让我失望,否则当分支完成时,我知道在条件中创建的变量会超出范围。然而,我动态地分配了这些数组,所以我不明白为什么我不能在程序的后面操作这些数组,因为指针应该保留下来。
//Prepare to store integers
if (flag == 1) {
int *Array;
Array = new int[input.length()];
}
//Prepare to store chars
else if (flag == 2) {
char *Array;
Array = new char[input.length()];
}
有人能解释一下吗?
在if
之前声明Array
。并且不能将不同类型的数组声明为一个变量,所以我认为应该使用to指针。
int *char_array = nullptr;
int *int_array = nullptr;
//Prepare to store integers
if (flag == 1) {
int_array = new int[input.length()];
}
//Prepare to store chars
else if (flag == 2) {
char_array = new char[input.length()];
}
if (char_array)
{
//do something with char_array
}
else if (int_array)
{
//do something with int_array
}
正如j_random_hacker所指出的,您可能希望更改程序设计,以避免大量的if
虽然您是对的,因为您在堆上动态分配了内存,所以在显式删除内存(或程序结束)之前,内存不会释放给系统,但当在中声明的块退出时,指向内存的指针就不在范围内了。因此,如果指针将在块之后使用,则需要在更大的范围内存在。
内存仍然分配(即占用宝贵的空间),在关闭}
之后无法访问它,因为此时程序将失去对其进行寻址的能力。为了避免这种情况,您需要将new[]
返回的指针分配给在外部作用域中声明的指针变量。
作为一个单独的问题,您似乎正在尝试分配两种不同类型之一的内存。如果您想方便地执行此操作,则必须使用void *
来保存指针,或者(不太常见)使用包含每种类型的指针的union
类型。无论哪种方式,您都需要维护状态信息,让程序知道进行了哪种分配通常,想要这样做表示设计不好,因为每次访问都需要打开此状态信息。
如果我正确理解你的意图,你要做的是:根据某些逻辑分配内存来存储int
或char
的n元素,然后在稍后的函数中将该数组作为int
或char
访问,而不需要单个if
语句。
如果以上理解是正确的,那么简单的答案是:"C++是一种强类型语言,你想要的是不可能的"。
然而。。。C++也是一种非常强大和灵活的语言,所以这里可以做些什么:
铸造。类似以下内容:
void * Array;
if(flag1) Array = new int[len]
else Array = new char[len];
// ... later in the function
if(flag) // access as int array
int i = ((int*)Array)[0];
是的,这太难看了,您必须在函数中添加if
。因此,这里有一个替代方案:模板
template<class T> T foo(size_t _len)
{
T* Array = new T[_len];
T element = Array[0];
return element;
}
另一种甚至更模糊的做事方式可能是使用union
:
union int_or_char {int i; char c;};
int_or_char *Array = new int_or_char[len];
if(flag) // access as int
int element = Array[0].i;
但无论如何(或第三种),编译器必须知道如何处理您试图处理的数据这一事实是无法解决的。
Turix的答案是正确的。您需要记住,这里分配了两件事,数组的内存和存储数组位置时的内存。
因此,即使数组中的内存是从堆中分配的,并且在任何需要的地方都可以用于代码,但存储数组位置的内存(数组变量)也会在堆栈中分配,一旦超出范围就会丢失。在这种情况下,if块结束。你甚至不能在同一if.的其他部分使用它
安德鲁的另一个不同的代码建议是:
void *Array = nullptr;
if (flag == 1) {
Array = new int[input.length()];
} else if (flag == 2) {
Array = new char[input.length()];
}
然后,您可以按照自己的意愿直接使用if。
这部分我不确定:如果你想知道它是int还是char,你可以使用typeid文字不起作用,至少我不能让它起作用。
或者,您可以使用您的标志变量来猜测它是什么类型。
- 并行用于C++17中数组索引范围内的循环
- 在函数范围内在堆栈上分配的数组在离开函数时是否总是被释放?
- 基于字节数组生成静态范围整数值
- 在C++中使用变量而不是"#define"来指定数组大小是不是一种糟糕的做法?(C错误:在文件范围内
- 使用基于数组和范围的 For 循环替换一些基本代码行
- C++中循环和 C 样式数组的范围工作
- Excel 不愉快地显示大型 2D 范围公式数组
- 变量未在此范围内声明 数组线性搜索
- 如何使用基于范围的for循环迭代Rapidjson文档(它本身就是一个JSON数组)
- 对于多个查询,查找在 l 到 r 范围内具有相同元素的最长公共子数组
- 基于多维标准::数组的范围
- 从文件中读取选定的行范围并存储到数组中
- 从原始指针(衰减的 C 样式数组)和大小生成范围::视图
- 给定数组范围的选择排序问题
- gcc8.2如何启用警告:数组下标在数组范围之上[-warray-bounds]
- 如何通过迭代通过它插入数组范围
- 输出在我的字符数组范围之外,同时使用 rand()
- C++中数组范围内的有效元素计数
- 访问超出数组范围不会产生任何错误
- 为什么我可以设置数组范围之外的值?