Я снова и снова получаю ошибку сегментации. Моя цель - скопировать файл в общую память, чтобы другой процесс чтения мог его прочитать. Чтобы скопировать файл, я выделил массив данных размера M в структуре. Я использовал NumberOfBuffers(N) и BufferSize(B), так что M=N*B. M - это половина файла. Таким образом, размер файла составляет примерно 2M. Я думаю, что в этом коде memcpy() генерирует ошибку сегментации. Первоначально моя цель - получить полный размер M в общей памяти через этот Writer.c, чтобы увидеть, что Copy по крайней мере работает. Моя операционная система — 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;
}
@KamilCuk Сейчас проверяю.
&M->Data[i*BufferSize]
будет обращаться за пределы массива Data
, когда i
не является 0
.
Это кажется странным: memset(M->Data, '\0', strlen(M->Data));
где там была написана строка? Лучше использовать размер буфера или, если он обнуляет строку, просто установите для первого элемента значение '\0'
.
@protik, внутренний для алгоритмов, доступ к памяти может быть проверен с помощью утверждений, т.е. Я бы обязательно написал assert(i * BufferSize * sizeof(Buf) < sizeof(M->Data));
Вы пробовали запускать на нем valgrind?
@KamilCuk, почему это «я» умножается? Я поставил &M->Data[i*BufferSize] в качестве смещения в структуре.
@CoffeeTableEspresso Нет.
@KamilCuk, хорошо, проверяю.
@protik извините, вы правы, это должно быть +
не *
там. i * BufferSize + sizeof(Buf)
.
@Kamilcuk для выражения I*Размер буфераSIZEOF (BUF) Размер файла: 1047714 Обратный размер файла: 1047714 Количество файлов буферов: 20 Проверка: 0 Проверка: 0. 2621440000 Проверка: 0. 524280000 Контроль: 7864320000 Объявления: 10485760000 Проверка: 13107200000 Проверка: 15728640000 Объявления: 18350080000 Проверка: 20971520000 Проверка: 23592960000 Ошибка сегментации (дамп ядра)
@protik, вам следует попробовать запустить на нем некоторые инструменты отладки, ответ, вероятно, придет довольно легко.
@KamilCuk Проверка этого выражения printf("\n Проверка: %d", i**BufferSize); исправил проблему. Ты великолепен.
Поскольку размер файла больше, чем NumberOfBuffers, этот код требует, чтобы модуль Mod Division не обращался к данным вне массива 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;
}
int BufferSize=51200; unsigned char Buf[BufferSize];
перейти от VLA кmalloc
, чтобы лучше обрабатывать случай стека. Что касаетсяmemcpy(&M->Data[i*BufferSize], Buf, sizeof(Buf)*sizeof(unsigned char));
, почему бы вам просто не проверитьif (i*BufferSize*sizeof(Buf) >= 512000) { error() }
? У вас в коде есть printfprintf("\n Number Of File Buffers: %d", NumberOfFileBuffers);
— так что же они печатают? Какова ценностьNumberOfFileBuffers
?FilePosition
?CopyableMemorySize
?sizeof(Buf)
?