2015-05-04 57 views
1

我是C新手,現在我正在學習mmap。我想從mmaped文件中獲得的第N個字節,但我得到這個錯誤Segmentation Fault (core dumped)當我測試的程序與gdb我得到的東西是不對的線printf("%d\n", (int) data[sk]);然後我print data,我得到從mmaped文件獲得第N個字節

(gdb) print data[sk] 
Cannot access memory at address 0xfe5f07d0 
(gdb) print data 
$1 = 0xfe5f0000 <Address 0xfe5f0000 out of bounds> 

我不知道爲什麼我得到這個錯誤。這裏是我的代碼

int main(int argc, char * argv[]){ 
    int sk; 
    int d; 
    char *data; 
    size_t s; 
    if(argc == 3){ 
     sk = atoi(argv[2]); 
     d = da_open(argv[1]); 
     s = da_fileSize(d); 
     data = (char*)da_mmap(d, s); 
     printf("File Size: %d\n", (int) s); 
     printf("%d\n", (int) data[sk]); // this line is bad. But why? 
     close(d); 
    } 
    return 0; 
} 

而且,這裏是我的全部代碼

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/mman.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <sys/time.h> 
#include <string.h> 

int da_open(const char *name); 
void *da_mmap(int d, size_t size); 
size_t da_fileSize(); 

int da_open(const char *name){ 
    int dskr; 
    dskr = open(name, O_RDWR); 
    if(dskr == -1){ 
     perror(name); 
     exit(1); 
    } 
    printf("dskr1 = %d\n", dskr); 
    return dskr; 
} 

void *da_mmap(int d, size_t size){ 
    void *a = NULL; 
    a = mmap(NULL, size, PROT_WRITE, MAP_SHARED, d, 0); 
    if(a == MAP_FAILED){ 
      perror("mmap failed"); 
      abort(); 
    } 
    return a; 
} 

size_t da_fileSize(int d){ 
    struct stat info; 
    if(fstat(d, &info) == -1) { 
     perror("fstat failed"); 
     exit(1); 
    } 
    return (size_t)info.st_size; 
} 

int main(int argc, char * argv[]){ 
    int sk; 
    int d; 
    char *data; 
    size_t s; 
    if(argc == 3){ 
     sk = atoi(argv[2]); 
     d = da_open(argv[1]); 
     s = da_fileSize(d); 
     data = (char*)da_mmap(d, s); 
     printf("File Size: %d\n", (int) s); 
     printf("%d\n", (int) data[sk]); 
     close(d); 
    } 
    return 0; 
} 

回答

5

我猜你也需要在你的mmap讀取權限:PROT_WRITE | PROT_READ

2

分段錯誤是,當你嘗試訪問您不擁有的內存空間。 它通常發生(就像你的情況)與數組。如果您的數組長度爲5個元素,並且您嘗試訪問第6個元素,則會出現分段錯誤,並且程序將停止。

所以在行printf("%d\n", (int) data[sk]);你的錯誤可能是在sk的值太大,你應該嘗試打印它來檢查它。

還應該檢查系統函數(不屬於你的函數)的返回值,例如open()或atoi()。如果打開失敗,你不會停止你的程序,你會有一個糟糕的時間:)