C++ 4k*4k浮动的mmap导致分段错误
我正在从文件中读取浮动矩阵。矩阵的维数为4k*4k。使用下面的程序,它会奇怪地导致在now()函数中重置。如果我将矩阵大小减少到1k*1k,它不会重置。虽然它正确读取浮点值,但最后几个值是垃圾值。我不知道这些垃圾价值是从哪里来的。我选择了BUFFSIZE 6的大小,因为它在浮点数中的位数大约是5-6。不确定它是否正确C++ 4k*4k浮动的mmap导致分段错误,c++,linux,mmap,C++,Linux,Mmap,我正在从文件中读取浮动矩阵。矩阵的维数为4k*4k。使用下面的程序,它会奇怪地导致在now()函数中重置。如果我将矩阵大小减少到1k*1k,它不会重置。虽然它正确读取浮点值,但最后几个值是垃圾值。我不知道这些垃圾价值是从哪里来的。我选择了BUFFSIZE 6的大小,因为它在浮点数中的位数大约是5-6。不确定它是否正确 #include <sys/time.h> #include <sys/types.h> #include <sys/stat.h> #incl
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <iostream>
#include <stdlib.h>
#include <sstream>
#define ROWS 4000
#define COLS 4000
#define BUFFSIZE 6
//#define USE_FREAD
#define USE_MMAP
double now()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec + tv.tv_usec / 1000000.;
}
int main()
{
double end_time;
double total_time;
int i, x, y, k;
for (k = 0; k < 1; k++)
{
double start_time = now();
FILE* in = fopen("resistence_file", "rb");
float arr[ROWS][COLS];
char temp[BUFFSIZE];
int val;
std::stringstream ss;
char* floats = (char*)mmap(
0,
ROWS * COLS * sizeof(float),
PROT_READ,
MAP_FILE | MAP_PRIVATE,
fileno(in),
0
);
fclose(in);
ss<<floats;
for (int i =0; i < ROWS; i++)
{
for (int j = 0; j < COLS; j++)
{
if ((ss.getline(temp, BUFFSIZE, ' ')) )
{
arr[i][j] = atof((temp));
}
}
}
for (int i =0; i < ROWS; i++)
{
for (int j = 0; j < COLS; j++)
{
printf("%.1f ", arr[i][j]);
}
printf("\n");
}
munmap(floats, ROWS * COLS * sizeof(float));
end_time = now();
total_time = end_time - start_time;
printf("It took %f seconds to read %d * %d matrix \n", total_time, ROWS, COLS);
}
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义行4000
#定义COLS 4000
#定义尺寸6
//#定义使用\u FREAD
#定义使用MMAP
现在加倍
{
结构时间值电视;
gettimeofday(&tv,NULL);
返回tv.tv\u sec+tv.tv\u usec/1000000。;
}
int main()
{
双端时间;
两倍的总时间;
int i,x,y,k;
对于(k=0;k<1;k++)
{
双启动时间=现在();
FILE*in=fopen(“电阻_文件”,“rb”);
浮动arr[行][COLS];
字符温度[BUFFSIZE];
int-val;
std::stringstream-ss;
字符*浮点=(字符*)mmap(
0,
行*COLS*sizeof(浮动),
PROT_READ,
MAP|U文件| MAP|U专用、,
文件编号(in),
0
);
fclose(in);
ssfloat arr[4000][4000];
将需要56Mb(假设sizeof(float)=4
)。这很可能比可用堆栈大
您需要移动arr
以获得静态持续时间
static float arr[ROWS][COLS];
...
int main()
或者动态地分配它,记住以后释放它
int main()
{
float (*arr)[COLS] = malloc(sizeof(*arr) * ROWS);
....
free(arr);
float arr[4000][4000];
将需要56Mb(假设sizeof(float)=4
)。这很可能比可用堆栈大
您需要移动arr
以获得静态持续时间
static float arr[ROWS][COLS];
...
int main()
或者动态地分配它,记住以后释放它
int main()
{
float (*arr)[COLS] = malloc(sizeof(*arr) * ROWS);
....
free(arr);
您正在映射一个sizeof(float)*K
字节的文件,就好像它包含二进制数据一样。如果它包含已知数量的二进制浮点数据,为什么以后还要像包含文本一样处理它?如果它包含文本,它与sizeof(float)有什么关系
?您是否绝对确定浮点数作为文本平均占用sizeof(float)
字节,包括空格分隔符?在大多数位置,每个数字大约有3个非空字符
您正在输入ss
一个字符串,该字符串可能以NUL结尾,也可能不以NUL结尾
与崩溃没有直接关系:这整个stringstream
和getline
的业务完全是对时空的浪费(好吧,至少浪费了64兆的空间和一些时间)。不要说任何程序员都不应该用六英尺长的杆接触的atof
。我希望您不要认真计划在生产代码中这样做。只需在原始阵列上使用std::strod
,即可代替所有这些
您正在映射一个sizeof(float)*K
字节的文件,就好像它包含二进制数据一样。如果它包含已知数量的二进制浮点数据,为什么以后还要像包含文本一样处理它?如果它包含文本,它与sizeof(float)有什么关系
?您是否绝对确定浮点数作为文本平均占用sizeof(float)
字节,包括空格分隔符?在大多数位置,每个数字大约有3个非空字符
您正在输入ss
一个字符串,该字符串可能以NUL结尾,也可能不以NUL结尾
与崩溃没有直接关系:这整个stringstream
和getline
的业务完全是对时空的浪费(好吧,至少浪费了64兆的空间和一些时间)。不要说任何程序员都不应该用六英尺长的杆来接触的atof
。我希望您不要认真计划在生产代码中这样做。只需在原始数组上使用std::strod
来代替这一切。将函数拆分为多行是为了提高可读性。您真的认为mmap
调用以这种方式编写更具可读性?将函数拆分为多行是为了提高可读性。你真的认为mmap
调用以这种方式编写更具可读性吗?谢谢,当我在动态内存上分配arr时,它没有导致SEGFULT。但我在最后几行中仍然看到0.0值0.0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.00.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0.0我不确定,但我猜ss.getline
有时会失败。您可以添加日志来检查这一点。看起来mmap从来没有映射过整个矩阵。如果文件中的大小为4K*4K,它将为映射字符串提供高达3.5K*3.5K的数据。但是如果我将文件中的大小减小到3k*3k,则映射为字符串仍然被弃用,数据不完整。我不知道问题出在哪里。我在映射字符串的末尾看到了垃圾字符。在我将float改为double后,它正常工作了。有人能解释一下为什么它正常工作吗?谢谢,当我在动态内存上分配arr时,它没有导致SEGFULT。但在过去的几个小时里,我仍然看到0.0的值0.0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 0.0我是