用C ++

时间:2016-11-09 11:27:33

标签: c++ c++11 matrix segmentation-fault malloc

我必须创建一个矩阵,其宽度和高度由从文件写入中获得的两个参数确定。但是,在某些情况下,当矩阵太大时,我得到了segmentation fault。我想可能是因为我是以静态的方式创建矩阵,所以我需要动态创建它,但是我的问题出现在这里,因为我不知道该怎么做。 我现在的代码是:

    FILE * fp;
    unsigned int width=0;
    unsigned int height=0;
  //Open the file. argv[4] parameter contains the file
  fp=fopen (argv[4],"r"); 
  //Go to the last position which indicates the size
    fseek(fp, 0, SEEK_END); 
  //Return to the start:
    rewind(fp);
  //The value of the first 4 bytes represent the width
    size_t return1 = fread(&width,4,1,fp);
  //The value of the next 4 bytes represent the height
    size_t return2 = fread(&height,4,1,fp);
 //Matrix creation
   if (return1 > 0 && return2 > 0) {
     unsigned int matrix[width][height];

2 个答案:

答案 0 :(得分:4)

如果您无法确定如何动态创建数组,我肯定会建议您使用vector类。

矢量是动态分配的,可以扩展。

std::vector<unsigned int> matrix{width * height};

请注意,我将向量设为一个维度,因为它在分配向量时确实简化了很多。

要访问您可以使用的特定坐标:

matrix.at(w * width + h);

wh是坐标,h显然应在0 <= h < height范围内。

如果要动态分配数组,则必须使用new运算符,然后必须记住使用正确的delete[]运算符进行清理。 Stack Overflow上有一个更好的答案:How do I declare a 2d array in C++ using new?

基本上它可以归结为:

unsigned int** matrix = new unsigned int*[width];
for (int w = 0; w < width; ++w) {
    matrix[w] = new unsigned int[height];
}

然后你必须记得再次删除矩阵,使用类似的东西:

for (int w = 0; w < width; ++w) {
    delete [] matrix[w];
}
delete [] matrix;

因此,换句话说,我建议您改为使用vector类。

当然,如果宽度和高度值足够大,偶数vector可能会失败,原因很简单,因为您试图分配太多内存。如果是这种情况,我认为您应该重新审视您的设计,并重新考虑如何制作。

请记住在使用向量时包含vector标题:

#include <vector>

答案 1 :(得分:2)

unsigned int matrix[width][height];

这有两个问题。

首先,widthheight不是编译时常量,这是C ++标准对数组大小所要求的。因此,您的计划格式不正确。您的编译器可能支持可变长度数组(VLA)作为语言扩展,因此它可能适用于您的编译器。

其次,VLA可以存储在堆栈中,并且堆栈空间有限。实际上,使用大型阵列可以轻松地溢出堆栈。你是对的,你需要动态分配数组。两者都是因为大小是动态的(假设您希望程序与其他不支持VLA的标准兼容编译器一起工作)并且因为它可以防止堆栈溢出。

创建动态数组的最简单方法是std::vector。 Tommy Andersen在他的回答中更深入地探讨了如何使用向量。