我一次又一次遇到细分错误。 我的目的是将文件复制到共享内存中,以便另一个读取器进程可以读取它。 为了复制文件,我在Struct中分配了M大小的数据数组。 我使用了NumberOfBuffers(N)和BufferSize(B),以便M = N * B。 M是文件的一半。因此,文件大小约为2M。 我认为这段代码中memcpy()正在生成细分错误。 最初,我的目标是通过Writer.c在共享内存中使用完整的M大小,以查看至少复制是否有效。 我的操作系统是Ubuntu。
#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[128];//POINTER PUTS DATA INTO NON-SHARED MEMORY
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
unsigned char Buf[BufferSize];
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{
strcpy(M->FileName, "xaa");
M->LastByteLength=0;
M->ReadPointer=-1;
M->WritePointer=-1;
memset(M->Data, '\0', strlen(M->Data));
}
char FileName[128]="xaa";
FILE *FP= fopen(FileName, "rb");
if(FP!= NULL){
struct stat StatBuf;
if(stat(FileName, &StatBuf)==-1){
printf("failed to fstat %s\n", FileName);
exit(EXIT_FAILURE);
}
long long FileSize=StatBuf.st_size;
printf("\n File Size: %lld", FileSize);
long long FilePosition=ftell(FP);
FilePosition=ftell(FP);
long long CopyableMemorySize=FileSize-FilePosition;
printf("\n Copyable File Size: %lld", CopyableMemorySize);
int NumberOfFileBuffers=CopyableMemorySize/BufferSize;
printf("\n Number Of File Buffers: %d", NumberOfFileBuffers);
for(int i=0; i<NumberOfFileBuffers; i++){
if(abs(M->WritePointer-M->ReadPointer)==NumberOfBuffers){
//WAIT
}else{
fseek(FP, i*BufferSize, SEEK_SET);
fread(Buf, sizeof(unsigned char), BufferSize, FP);
memcpy(&M->Data[i*BufferSize], Buf, sizeof(Buf)*sizeof(unsigned char));
}
}
fclose(FP);
}
close(SD);
return 0;
}
答案 0 :(得分:1)
由于文件大小大于NumberOfBuffers,因此此代码需要Mod除法,以便不能访问M-> Data数组之外的数据。
#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[128];//POINTER PUTS DATA INTO NON-SHARED MEMORY
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
unsigned char Buf[BufferSize];
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{
strcpy(M->FileName, "xaa");
M->LastByteLength=0;
M->ReadPointer=-1;
M->WritePointer=-1;
memset(M->Data, '\0', strlen(M->Data));
}
char FileName[128]="xaa";
FILE *FP= fopen(FileName, "rb");
if(FP!= NULL){
struct stat StatBuf;
if(stat(FileName, &StatBuf)==-1){
printf("failed to fstat %s\n", FileName);
exit(EXIT_FAILURE);
}
long long FileSize=StatBuf.st_size;
printf("\n File Size: %lld", FileSize);
long long FilePosition=ftell(FP);
FilePosition=ftell(FP);
long long CopyableMemorySize=FileSize-FilePosition;
printf("\n Copyable File Size: %lld", CopyableMemorySize);
int NumberOfFileBuffers=CopyableMemorySize/BufferSize;
printf("\n Number Of File Buffers: %d", NumberOfFileBuffers);
for(int i=0; i<NumberOfFileBuffers; i++){
int BufferModCount=i%NumberOfBuffers;
if(abs(M->WritePointer-M->ReadPointer)==NumberOfBuffers){
//WAIT
}else{
fseek(FP, i*BufferSize, SEEK_SET);
fread(Buf, sizeof(unsigned char), BufferSize, FP);
printf("\n Checking: %d", i*BufferSize);
memcpy(&M->Data[BufferModCount*BufferSize], &Buf, sizeof(Buf)*sizeof(unsigned char));
}
}
fclose(FP);
}
close(SD);
return 0;
}