首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C共享内存读写器分段故障

C共享内存读写器分段故障
EN

Stack Overflow用户
提问于 2019-05-21 03:20:58
回答 1查看 53关注 0票数 1

这是一个同步的阅读器和写入器。目标是通过共享内存在这两个进程之间传递数据。Writer通过一个结构打开一个共享内存,并写入一些数据。我收到分段故障(核心转储)错误消息。代码是在Ubuntu中通过以下命令编译的。

代码语言:javascript
运行
复制
g++ Writer.c -o Writer -lrt
g++ Reader.c -o Reader -lrt

这两个进程是由-

代码语言:javascript
运行
复制
./Writer
./Reader    

The Writer.c

代码语言:javascript
运行
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>

int main(void){
    struct MemData{
        char* FileName;
        int LastByteLength;
        int ReadPointer;
        int WritePointer;
        char Data[512000];//MEMORY BLOCK SIZE: 500 KB
    };
    int SD;
    struct MemData *M;
    int NumberOfBuffers=10;
    int BufferSize=51200;//FILE BUFFER SIZE 50 KB

    SD= shm_open("/program.shared", O_RDWR|O_CREAT, S_IREAD|S_IWRITE);
    if(SD< 0){
        printf("\nshm_open() error \n"); 
        return EXIT_FAILURE; 
    }
    fchmod(SD, S_IRWXU|S_IRWXG|S_IRWXO); 
    if(ftruncate(SD, sizeof(MemData))< 0){
        printf ("ftruncate() error \n");
        return EXIT_FAILURE; 
    }
    //THE FOLLOWING TYPECASTING AVOIDS THE NEED TO ATTACH THROUGH shmat() in shm.h HEADER I GUESS.
    M=(struct MemData*)mmap(NULL, sizeof(MemData), PROT_READ|PROT_WRITE, MAP_SHARED, SD, 0);
    if(M== MAP_FAILED){
        printf("mmap() error");
        return EXIT_FAILURE;
    }else{
        M->FileName=(char*)"xaa";
        M->LastByteLength=0;
        M->ReadPointer=-1;
        M->WritePointer=-1;
        memset(M->Data, '\0', strlen(M->Data));
    }
    /*
    FILE *FP= fopen(FileName, "rb");
    if(FP!= NULL){
        unsigned long int FilePosition;
        fseek(FP, 0, SEEK_SET);
        FilePosition=ftell(FP);
        fclose(FP);
    }
    */
    close(SD);
    return 0;
}

Reader.c

代码语言:javascript
运行
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>

int main(void){
    struct MemData{
        char* FileName;
        int LastByteLength;
        int ReadPointer;
        int WritePointer;
        char Data[512000];//MEMORY BLOCK SIZE: 500 KB
    };
    int SD;
    struct MemData *M;
    int NumberOfBuffers=10;
    int BufferSize=51200;//FILE BUFFER SIZE 50 KB

    SD= shm_open("/program.shared", O_RDWR|O_CREAT, S_IREAD|S_IWRITE);
    if(SD< 0){
        printf("\nshm_open() error \n"); 
        return EXIT_FAILURE; 
    }
    fchmod(SD, S_IRWXU|S_IRWXG|S_IRWXO); 
    if(ftruncate(SD, sizeof(MemData))< 0){
        printf ("ftruncate() error \n");
        return EXIT_FAILURE; 
    }
    //THE FOLLOWING TYPECASTING AVOIDS THE NEED TO ATTACH THROUGH shmat() in shm.h HEADER I GUESS.
    M=(struct MemData*)mmap(NULL, sizeof(MemData), PROT_READ|PROT_WRITE, MAP_SHARED, SD, 0);
    if(M== MAP_FAILED){
        printf("mmap() error");
        return EXIT_FAILURE;
    }else{
        printf("\n%s", M->FileName);
        printf("\n%d", M->LastByteLength);
        printf("\n%d", M->ReadPointer);
        printf("\n%d", M->WritePointer);
    }
    /*
    FILE *FP= fopen(FileName, "rb");
    if(FP!= NULL){
        unsigned long int FilePosition;
        fseek(FP, 0, SEEK_SET);
        FilePosition=ftell(FP);
        fclose(FP);
    }
    */
    munmap(M,sizeof(MemData));
    close(SD);
    return 0;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-21 03:34:38

根据您的评论,这个问题是由于您分配和传递FileName值的方式造成的。

M->FileName=(char*)"xaa";

这会导致M->FileName在写进程的内存中持有一个指向字符串的指针。在读取器进程中取消引用此指针会导致分段错误,因为文件名存储在不与读取器共享的写入器进程内存中。您需要将字符本身存储在共享内存中,而不是指向编写器进程内存的指针。

如果可以安全地假定文件名字符串的最大长度,则可以更改结构以存储整个字符串,而不是指针:将char* FileName;更改为char FileName[256];或其他固定长度值。进行以下更改后,您将需要使用strcpy而不是直接赋值:将M->FileName=(char*)"xaa";更改为strcpy(M->FileName, "xaa");

如果需要动态长度字符串,可以再次调用mmap为该字符串分配共享内存,然后将指向该共享内存字符串的指针存储在FileName中。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56226936

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档