简体   繁体   中英

mmap of 4k * 4K floats leading to segmentation fault

I'm reading matrix of floats from file. Dimensions of matrix are 4k * 4K. With the below program, it just leads to reset in now() function strangely. if I reduce the matrix size to 1k * 1K, it doesn't reset. Though it reads floats correctly but last few values are junk. I don't know where these junk values are coming from. I took the size of BUFFSIZE 6 since it digits in the floating number is going to be around 5-6. Not sure if it is correct.

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

float arr[4000][4000]; will require 56Mb (assuming sizeof(float)=4 ). This is very likely to be larger than your available stack.

You'll need to either move arr to have static duration

static float arr[ROWS][COLS];
...
int main()

or allocate it dynamically, remembering to free it later

int main()
{
    float (*arr)[COLS] = malloc(sizeof(*arr) * ROWS);
    ....
    free(arr);
  1. You are mapping a file of sizeof(float)*K bytes as if it contained binary data. If it contains known amount of binary floating point data, why are you trying to work with later it as if it contained text? If it contains text, what does it have to do with sizeof(float) ? Are you absolutely sure your floating-point numbers occupy, as text , sizeof(float) bytes on the average, including the space delimiter? That's about 3 non-blank characters per number at most places.
  2. You are feeding ss a string which may or may not be NUL-terminated.

Not directly related to the crash: this whole business of stringstream and getline here is a complete waste of spacetime (OK at least a waste of 64 megabytes of space and of at least some time). Not speaking of atof which no programmer should ever touch with a six feet long pole. I hope you don't seriously plan to do that in production code. Just use std::strtod on the original array in place of all this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM