C共享内存读写器分段错误

C共享内存读写器分段错误,c,ubuntu,C,Ubuntu,这是一个同步的读写器。目标通过共享内存在这两个进程之间传递数据。 写入程序通过结构打开共享内存并写入一些数据。我收到分段错误(核心转储)错误消息。 代码是通过Ubuntu中的以下命令编译的 g++ Writer.c -o Writer -lrt g++ Reader.c -o Reader -lrt 这两个过程由- ./Writer ./Reader 作者 #include <stdio.h> #include <stdlib.h> #include <

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

g++ Writer.c -o Writer -lrt
g++ Reader.c -o Reader -lrt
这两个过程由-

./Writer
./Reader    
作者

#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;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
内部主(空){
结构MemData{
字符*文件名;
int LastByteLength;
int读取指针;
int-WritePointer;
字符数据[512000];//内存块大小:500KB
};
国际标准差;
结构MemData*M;
int NumberOfBuffers=10;
int BufferSize=51200;//文件缓冲区大小50 KB
SD=shm_open(“/program.shared”,O_RDWR | O|u CREAT,S|u IREAD | S|IWRITE);
如果(SD<0){
printf(“\nshm_open()错误\n”);
返回退出失败;
}
fchmod(SD,S|u IRWXU | S|u IRWXG | S|u IRWXO);
if(ftruncate(SD,sizeof(MemData))<0){
printf(“ftruncate()错误\n”);
返回退出失败;
}
//下面的类型转换避免了通过shm.h标题中的shmat()附加的需要。
M=(struct MemData*)mmap(NULL,sizeof(MemData),PROT_READ | PROT_WRITE,MAP_SHARED,SD,0);
如果(M==映射_失败){
printf(“mmap()错误”);
返回退出失败;
}否则{
M->FileName=(char*)“xaa”;
M->LastByteLength=0;
M->ReadPointer=-1;
M->WritePointer=-1;
memset(M->Data,'\0',strlen(M->Data));
}
/*
FILE*FP=fopen(文件名,“rb”);
如果(FP!=NULL){
无符号长整型文件位置;
fseek(FP,0,SEEK_集);
FilePosition=ftell(FP);
fclose(FP);
}
*/
关闭(SD);
返回0;
}
读者

#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;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
内部主(空){
结构MemData{
字符*文件名;
int LastByteLength;
int读取指针;
int-WritePointer;
字符数据[512000];//内存块大小:500KB
};
国际标准差;
结构MemData*M;
int NumberOfBuffers=10;
int BufferSize=51200;//文件缓冲区大小50 KB
SD=shm_open(“/program.shared”,O_RDWR | O|u CREAT,S|u IREAD | S|IWRITE);
如果(SD<0){
printf(“\nshm_open()错误\n”);
返回退出失败;
}
fchmod(SD,S|u IRWXU | S|u IRWXG | S|u IRWXO);
if(ftruncate(SD,sizeof(MemData))<0){
printf(“ftruncate()错误\n”);
返回退出失败;
}
//下面的类型转换避免了通过shm.h标题中的shmat()附加的需要。
M=(struct MemData*)mmap(NULL,sizeof(MemData),PROT_READ | PROT_WRITE,MAP_SHARED,SD,0);
如果(M==映射_失败){
printf(“mmap()错误”);
返回退出失败;
}否则{
printf(“\n%s”,M->FileName);
printf(“\n%d”,M->LastByteLength);
printf(“\n%d”,M->ReadPointer);
printf(“\n%d”,M->WritePointer);
}
/*
FILE*FP=fopen(文件名,“rb”);
如果(FP!=NULL){
无符号长整型文件位置;
fseek(FP,0,SEEK_集);
FilePosition=ftell(FP);
fclose(FP);
}
*/
munmap(M,sizeof(MemData));
关闭(SD);
返回0;
}

根据您的评论,问题在于您分配和传递
文件名的方式

M->FileName=(char*)“xaa”

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

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


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

读写器是哪个进程?我猜是读者;如果注释掉
printf(“\n%s”,M->FileName”),会发生什么情况行?让我检查一下。现在在注释printf(“\n%s”,M->FileName”)后没有分段错误;line@John,如何修复此printf()行?文件名指向编写器进程中的非共享内存。将其更改为
char文件名[100]@stark,我已经按照你的建议做了更改,然后这个任务M->FileName=“xaa”;导致错误的原因:将“const char[4]”赋值为“char[128]”时类型不兼容。请告诉我如何在结构中存储文件名?请参阅我的编辑。您可以将该字符串更改为固定宽度的字符数组,也可以在共享内存中分配该字符串。我已根据您的建议进行了更改,然后此分配M->FileName=“xaa”;导致错误的原因:将“const char[4]”赋值为“char[128]”时不兼容的类型使用
strcpy
而不是直接赋值。编辑答案