我必须创建一个矩阵,其宽度和高度由从文件写入中获得的两个参数决定。但是,在某些情况下,当矩阵太大时,我有一个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];
如果你不知道如何动态创建数组,我绝对建议你使用vector
类。
向量是动态分配的,并且可以缩放。
std::vector<unsigned int> matrix{width * height};
请注意,我将向量设置为单维度,因为它在分配向量时确实简化了很多。
要访问一个特定的坐标,可以使用:
matrix.at(w * width + h);
其中w
和h
为坐标,h
显然应该在0 <= h < height
范围内。
如果你要动态分配你的数组,你将不得不使用new
操作符,然后必须记住清理之后以及使用适当的delete[]
操作符。在Stack Overflow上有一个更好的答案:我如何在c++中使用new声明一个2d数组?
基本上可以归结为:
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时,请记住包含vector
头:
#include <vector>
unsigned int matrix[width][height];
这有两个问题。
首先,width
和height
不是编译时间常数,这是c++标准对数组大小的要求。因此,您的程序是病态的。您的编译器可能支持可变长度数组(VLA)作为语言扩展,因此它可能与您的编译器一起工作。
其次,VLA可以存储在堆栈上,而堆栈空间是有限的。实际上,对于一个大数组,很容易使堆栈溢出。你是正确的,你需要动态地分配数组。因为VLA的大小是动态的(假设您希望您的程序与其他不支持VLA的标准兼容编译器一起工作),并且因为它可以防止堆栈溢出。
创建动态数组最简单的方法是std::vector
。Tommy Andersen在他的回答中更深入地探讨了如何使用向量。