2013-06-18 22 views
0

我正在從文件讀取浮動矩陣。矩陣的尺寸是4k * 4K。在下面的程序中,它會導致現在()函數奇怪地重置。如果我將矩陣大小減小到1k * 1K,則不會重置。雖然它正確地讀取浮動,但最後幾個值是垃圾。我不知道這些垃圾價值來自哪裏。由於浮點數的位數在5-6左右,因此我將BUFFSIZE的大小設爲6。不知道它是否正確。4k * 4K浮動的mmap導致分段錯誤

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

爲了提高可讀性,完成了拆分到多行的功能。你真的認爲你的'mmap'調用更具可讀性嗎? – Wug

回答

6

float arr[4000][4000];將需要56MB(假設sizeof(float)=4)。這很可能比您的可用堆棧大。

你需要或者移動arr具有靜態持續時間

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

或動態分配它,記住它free後來

int main() 
{ 
    float (*arr)[COLS] = malloc(sizeof(*arr) * ROWS); 
    .... 
    free(arr); 
+0

謝謝,當我在動態內存中分配arr時,沒有導致段錯誤。但是我仍然可以看到最後幾百個浮點數的0.0值。你能建議它爲什麼可以? 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 – Pthread

+0

我不確定,但會猜測'ss。 getline'有時會失敗。你可以添加日誌記錄來檢查這一點。 – simonc

+0

看來mmap從不映射整個矩陣。如果文件大小爲4K * 4k,則會爲映射的字符串提供高達3.5K * 3.5K的數據。但是,如果我將文件大小減小到3k * 3K,映射字符串仍然被不完整的數據所取代。我不知道是什麼問題。我在映射的字符串 – Pthread

0
  1. 你映射的sizeof(float)*K字節的文件就好像它包含二進制數據一樣。如果它包含已知數量的二進制浮點數據,那麼爲什麼您稍後嘗試使用它,就好像它包含文本一樣?如果它包含文本,那麼與sizeof(float)有什麼關係?你絕對確定你的浮點數佔用,爲文本sizeof(float)字節的平均值,包括空格分隔符?在大多數地方,每個數字大約有3個非空白字符。
  2. 你餵養ss其可以是或可以不是NUL結尾的字符串。

沒有直接關係的崩潰:這整個的stringstreamgetline這裏業務的時空完全是浪費(OK至少的空間64兆和至少一些浪費時間)。沒有談到atof哪個程序員不應該碰到一個六英尺長的杆子。我希望你不要認真計劃在生產代碼中這樣做。只需在原始陣列上使用std::strtod代替所有這些。

+0

我有一個文件,其中包含浮動(4k * 4k)。我從第三方收到它。我需要從這個文件中提取浮點數並將其存儲在矩陣中,並在矩陣上執行線性方程式算法。如果我試圖將它映射爲浮點指針,它不會給我任何有意義的數據,但如果我將它映射爲文本,它會給我值。我同意你的意見。但是我怎麼知道,mmap函數中的緩衝區大小應該是多少,因爲我知道它是一個包含4k * 4k浮點數的文件。 – Pthread

+0

如果你不知道如何確定文件的大小,你會問一個問題。 「如何確定C++文件的大小?」將是一個相當好的開始。嘗試使用Google搜索。 –