C++可变大小缓冲区实现:解决变长数组编译报错问题
解决C++构造函数中变长数组的编译错误(expression must have a constant size)
我之前在Visual Studio里写类似的滑动平均类时,也踩过这个坑!问题出在标准C++不支持变长数组(VLA)——也就是你写的double buffer[buffersize]这种用非常量表达式定义大小的数组,这是C99的特性,VC编译器并不支持,所以才会报expression must have a constant size的错误。
而且原代码还有两个隐藏问题:
- 构造函数里的
buffer是局部变量,构造函数执行完就销毁了,AddSample和Average根本访问不到这个数组 buffersize也没存在类成员里,其他成员函数根本拿不到缓冲区大小的值
用std::vector的正确解决方案(和你提到的方法一致)
std::vector是标准C++专门用来处理动态大小容器的工具,既能实现自定义缓冲区大小,又能自动管理内存,完全避开变长数组的问题。下面是修正后的完整代码:
#include <iostream> #include <cmath> #include <stdlib.h> #include <windows.h> #include <vector> // 别忘了包含vector头文件 using namespace std; class Running_Average { public: double average = 0; // 把buffer和buffersize作为类成员,buffer用vector代替数组 vector<double> buffer; int buffersize; // 成员函数声明 double Average(void); void AddSample(double); Running_Average(int); }; // 构造函数:初始化vector的大小和初始值,同时保存缓冲区大小 Running_Average::Running_Average(int size) : buffersize(size), buffer(size, 0.0) {} void Running_Average::AddSample(double val) { // 从后往前移位,注意用局部变量i,避免类成员i的干扰 for (int i = buffersize - 1; i > 0; --i) { buffer[i] = buffer[i - 1]; } buffer[0] = val; } double Running_Average::Average(void) { double sum = 0.0; // 用局部sum,避免类成员sum的状态残留 for (int i = 0; i < buffersize; ++i) { sum += buffer[i]; } average = sum / buffersize; return average; } int main() { double value; int i; // 创建对象时必须传入缓冲区大小,比如这里设为10(对应原代码里的循环逻辑) Running_Average test(10); // 先填充初始样本 for (i = 40; i < 50; ++i) { test.AddSample(i); } while (1) { i = rand() % 100; test.AddSample(i); value = test.Average(); cout << "\n当前滑动平均值:" << value << "\n" << endl; Sleep(1000); } }
关键修改点说明:
- 替换数组为
std::vector:把原来的局部变长数组换成类成员vector<double> buffer,构造函数里用初始化列表直接初始化vector的大小和初始值 - 保存缓冲区大小:把
buffersize设为类成员,确保所有成员函数都能访问到 - 避免全局/类成员变量污染:
AddSample和Average里用局部的i,不要用类成员的i,防止意外的变量值干扰 - 修正main函数的错误:原代码里
Running_Average test;没有传参数,构造函数需要一个int,所以必须传入缓冲区大小(比如10)
你提到已经用std::vector解决了问题,真的选对了!这比用new[]手动分配数组安全多了,vector会自动处理内存释放,不用怕内存泄漏。
内容的提问来源于stack exchange,提问作者Andrew Schroeder
相关产品推荐
相关产品推荐

