首页 > 解决方案 > 为什么会出现缓冲区溢出?我怎样才能避免它?[C++]

问题描述

介绍:

大家好,我有一个.csv文件,其中包含分辨率为 1280x720(宽 x 高)的图像的 (x, y, z) 坐标。在这些数据点中,它包含代表该特定像素深度的 z 值。CSV 文件中有 1280x720 = 921,600 个点。

CSV 文件:最后一行最后一列

问题:

最初,我想将 2D 数组中的这 921,600 个点复制到我自己的程序中进行处理。我写了double Array2D[1280][720];但是程序崩溃了,很可能是因为 Stack Overflow。我的其他新方法几乎可以工作,但似乎也遇到了类似的问题,是缓冲区溢出吗?

在我自己对下面代码的测试中,从点 (0, 0) 到 (1279, 565) 查询 (x, y) 是有效的,但 565 之后的任何内容都是无效的。例如,在 .CSV 文件中,在点 (1279, 565),实际值为 1.589,我的程序设法获得了该值。在点 (1279, 566),实际值为 1.579,但我的程序返回 0 值。

控制台测试程序

这是某种缓冲区溢出吗?我能做些什么来解决这个问题?

CSV 文件: 链接到 .CSV 文件

完全简化的代码:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <memory>

template <class T, size_t W, size_t H>
class Array2D {
public:
    const int width = W;
    const int height = H;
    typedef typename T type;

    Array2D() {
        buffer.resize(width*height);
    }

    T &operator() (int x, int y) {
        return buffer[y*width + x];
    }

    const T &operator() (int x, int y) const {
        return buffer[y*width + x];
    }

private:
    std::vector<T> buffer;
};

int main() {
    char eater; // Charater to remove ',' and '\n' in a .CSV file
    int xs, ys; // User queried points, X & Y coordinates

    Array2D<double, 1281, 721> a;

    // Opening (x, y, z) .CSV file with 921,600 points
    std::ifstream coordinatesFile;
    coordinatesFile.open("test2.csv_Depth_3068.csv");

    std::cout << "COPYING" << std::endl;

    // Copying the z(depth) data into a Vector
    for (int y = 1; y < 720; y++) { // Iterating through 720 rows
        for (int x = 1; x < 1280; x++) { // Iterating through 1280 columns
            coordinatesFile >> a(x, y); // Copying the value with X, Y coordinates
            coordinatesFile >> eater; // Remove the ',' after each z(depth) value
        }
        coordinatesFile >> eater; // Removes the '\n' after every row in a .CSV file, should run 720 times since there are 720 rows which means there are 720 '\n's
    }

    // For user to Query the data stored in vector
    while (1) {
        std::cout << "Enter X val: ";
        std::cin >> xs;
        std::cout << "Enter Y val: ";
        std::cin >> ys;

        std::cout << "Value = " << a(xs, ys) << std::endl;
    }

    coordinatesFile.close();
    std::cin.get();
    std::cin.ignore();
}

标签: c++csvbufferbuffer-overflow

解决方案


数组(和s)具有从到std::vector的有效索引。0size - 1

也不知道你为什么定义

Array2D<double, 1281, 721> a;

采用:

Array2D<double, 1280, 720> a;

for (int y{}; y < 720; ++y) {
    for (int x{}; x < 1280; ++x) {
        if (!(coordinatesFile >> a(x, y) >> std::noskipws >> eater >> std::skipws)
            && !coordinatesFile.eof() && eater != ',' && eater != '\n')
        {
            std::cerr << "Format error at " << x + 1 << '/' << y + 1 << " :(\n\n";
            return EXIT_FAILURE;
        }
    }
}

应该做的伎俩。


推荐阅读