c++ - 在 esp32 上分配向量后损坏堆
问题描述
我正在尝试在 esp32-cam 上计算光流(基于 lucas kanade)。我试图通过仅对数组的 2 个小缓冲区进行操作来节省内存。我仍然有一个错误损坏堆:
测试0
在分配出转化之前
分配出转化后
在分配出转化之前
分配出转化后
在分配出转化之前
分配出转化后
在分配出转化之前
CORRUPT HEAP:multi_heap.c:432 在 0x3fff7114 检测到 abort() 在核心 0 上的 PC 0x40090a7f 上调用
这是我的代码,由 1D 卷积和转置组成,以执行单独的等效 2D 卷积:
template<typename T>
void
conv(uint8_t *in, const std::vector<T> &g, const int nf) {
//int const nf = f.size();
int const ng = g.size();
int const n = nf + ng - 1;
uint8_t *f = in;
Serial.println("bfore allocate out conv");
std::vector<T> out(n, T()); // memory leak CORRUPT HEAP
Serial.println("after allocate out conv");
for(auto i(0); i < n; ++i) {
int const jmn = (i >= ng - 1)? i - (ng - 1) : 0;
int const jmx = (i < nf - 1)? i : nf - 1;
for(auto j(jmn); j <= jmx; ++j) {
out[i] += (f[j] * g[i - j]);
}
}
out.erase(out.begin(), out.begin() + ng / 2 + 1);
// Rescale to 0..255
auto max = *std::max_element(out.begin(), out.end());
auto min = *std::min_element(out.begin(), out.end());
float x;
for(auto v : out) {
x = (v - min) * 255.0 / max;
*(f++) = (uint8_t)x;
}
std::vector<T>().swap(out);
}
void transpose(uint8_t *f, int w, int h) {
for(auto i(0); i < h; ++i)
for(auto j(0); j < w; ++j)
std::swap(f[w * i + j], f[w * j + i]);
}
void LK_optical_flow(uint8_t *src1, uint8_t *src2, uint8_t *output, int w, int h)
{
Serial.println("test0");
std::vector<float> Kernel_Dy = {1, 2, 1};
std::vector<float> Kernel_Dx = {-1, 0, 1};
std::vector<float> Kernel_Dt = {1/3.0, 1/3.0, 1/3.0};
uint8_t *fx = src1;
uint8_t *fy = new uint8_t[w * h];
uint8_t *ft = src2;
memcpy(fy, fx, w * h * sizeof(uint8_t));
// Sobel Dx
conv(fx, Kernel_Dx, w*h);
transpose(fx, w, h);
conv(fx, Kernel_Dy, w*h);
transpose(fx, w, h);
// Sobel Dy
conv(fy, Kernel_Dy, w*h);
transpose(fy, w, h);
conv(fy, Kernel_Dx, w*h); // memory leak
transpose(fy, w, h);
// Dt
//conv(src2, Kernel_Dt, w*h);
...
}
显然,泄漏来自我fy
在第二次调用期间分配的第二个缓冲区,conv(fy, ...)
当它分配为向量时。我究竟做错了什么?
解决方案
与不一样,将访问w
和写入越界内存。h
transpose
根据您的评论,您有w
96 个和h
大约 48 个。swap
in的第二个参数transpose
将访问f[w * (w - 1) + h * (h - 1)]
超过w * h
您分配的元素。这将更改尚未分配的内存,并且在您的情况下会破坏您的库用于跟踪已分配内存的数据(仅在分配空闲时检测到,并且可能不会立即检测到)。
该解决方案涉及重写transpose
以正确转置矩形矩阵。(这涉及交换w
和h
返回的矩阵。)
推荐阅读
- c# - .Net Core 服务未注册
- java - Excel corrput 由于使用 apache-poi 库创建下拉列表
- kubernetes - Prometheus-operator 彻底破坏了 DigitalOcean 上的整个 Kubernetes 集群
- excel - Is there an Excel formula to find/match words in a range of cells
- material-design - 来自 node_modules 的 scss 文件在 React js 中出错
- amazon-web-services - 无法使用映射模板解析来自 DynamoDB 的 AWS API 响应
- reactjs - 如何处理 React Project 中的后退按钮单击?
- django - Django Signal post_save()
- python - 带有 HDFStore 的 pandas.DataFrame.convert_dtypes 会导致属性错误?
- python - 每隔几秒使用 python 检索 SQL 查询