为什么会出现缓冲区溢出?我该如何避免呢? [C ++]

时间:2018-11-08 06:59:40

标签: c++ csv buffer buffer-overflow

简介:

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

CSV File: Last Row Last Column

问题:

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

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

Console Test Program

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

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

1 个答案:

答案 0 :(得分:4)

数组(和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;
        }
    }
}

应该可以解决问题。