是否可以使用以下代码模仿动态分配的行为。例如,我们不知道存储在文件中的整数的确切数量,我们将读取该文件,然后将其存储在名为Hello的数组中。
int x;
int n=0;
ifstream input("a.dat");
while (!input.eof())
{
input >> x;
n++;
}
input.close();
int Hello[n];
cout << "n= " << n << endl;
int i=0;
while (!input.eof())
{
input >> Hello[i];
i++;
}
答案 0 :(得分:2)
是否可以使用。模仿动态分配的行为 以下代码。
不,主要区别在于程序中的数组存储在堆栈中,而所有动态内存分配都在堆上进行。
您正在做的事情,在您的代码中使用C ++ C语言C95标准的VLA特性。使用g ++编译器中的-pedantic选项进行编译将揭示这一点。由于c ++没有直接支持它,并且它是一个特定于实现的语言扩展,如果你的目标是编写可移植的代码,那么使用它并不是一个好主意。
VLA使用alloca(
),在运行时在堆栈上分配内存,并讨论了这种技术的缺点here。
此外,VLA在运行时在堆栈上分配内存,如果值超出范围,程序就会崩溃,而使用VLA快速创建几个字节的数组是可以的,但是创建不确定数量的大内存可能不会安全,最好使用动态内存分配来处理它。
答案 1 :(得分:1)
int Hello[n];
NOT dynamic
分配。如果要以这种方式声明n
,则Hello
必须是编译时常量。
尝试:
int* Hello = new int[n];
并且在完成使用后不要忘记释放内存:
delete[] Hello;
答案 2 :(得分:1)
这是一些编译器允许的扩展,但不完全是C ++的一部分。
int Hello[n];
作为替代方案,您可以自己分配内存:
int* Hello = new int[n];
并自己释放:
delete[] Hello;
但您可以通过std::vector
中的<vector>
来避免手动记忆管理。其构造函数之一接受初始大小:
vector<int> Hello(n); // Vector with n elements, all initially 0.
您也可以在不调整大小的情况下设置初始容量,进行一次分配:
vector<int> Hello; // Empty vector.
Hello.reserve(n); // Allocate space for n elements; size() is still 0.
然后阅读int
并使用push_back
插入值:
int value;
while (input >> value)
Hello.push_back(value);
注意使用input >> value
作为循环条件 - 只要读取成功,就会读取。 eof()
仅在最后一次读取操作因文件意外结束而失败时才返回true,这不太可能完全符合您的要求。
答案 3 :(得分:0)
开始第二次
while (!input.eof())
永远都会失败。这终止了第一个,然后你开始关闭输入流!