为什么会出现缓冲区溢出?我怎样才能避免它? [C++]

Why am I getting Buffer Overflow? How can I avoid it? [C++]

简介:

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

问题:

本来想把这921600个点二维数组复制到自己的程序中处理。我写了 double Array2D[1280][720]; 但程序崩溃了,很可能是因为 Stack Overflow。我的另一个新方法几乎可以工作,但似乎也遇到了类似的问题,是缓冲区溢出吗?

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

这是某种缓冲区溢出吗?我该怎么做才能解决这个问题?

CSV 文件: Link to .CSV File

完全简化代码:

#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();
}

数组(和 std::vectors)具有从 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;
        }
    }
}

应该可以解决问题。