在我的createFileAddRecordAndRead()
函数中,我创建了一个FixedLengthRecordFile
对象的实例(处理文件I / O),然后使用它将记录写入文件,然后再读回来
FixedLengthRecordFile file;
// The following opens the file in "wb+" mode because
// in order to write a record I need to read something else first
file.create("fixedfile.txt",record.getRecordSize(),1);
file.write(0,record); // Write the record in the offset 0
file.close();
file.open("fixedfile.txt","rb");
file.read(0,readRecord); // Read record 0 and store it in a variable
但它不起作用(实际上,它确实有效,因为记录被写入并回读,但valgrind
抱怨)。但是,如果我执行写作和任务的任务单独阅读(即有两个实例 - 一个要写,一个要阅读),valgrind
不会抱怨。
这是FixedLengthRecordFile
类的一些代码......
int FixedLengthRecordFile :: create (std::string fileName, int recSize, int p_maxRecs)
{
// Initialize file attributes
recordSize = recSize;
maxRecs = p_maxRecs;
file = fopen(fileName.c_str(),"wb+");
if (file == NULL)
return RES_ERROR;
if (initFileHeader() == RES_OK)
{
if (initEmptyRecords() == RES_OK)
return RES_OK;
}
return RES_ERROR;
}
int FixedLengthRecordFile :: open (std::string fileName, std::string mode)
{
file = fopen(fileName.c_str(),mode.c_str());
if (file == NULL) {
return RES_ERROR;
}
struct header head;
if (getFileHeader(head) == RES_ERROR) {
return RES_ERROR;
}
recordSize = head.h_recordSize;
maxRecs = head.h_maxRecords;
return RES_OK;
}
int FixedLengthRecordFile :: close ()
{
int result = fclose(file);
if (result == 0) {
std::cout << "File closed. " << std::endl;
return RES_OK;
}
return RES_ERROR;
}
int FixedLengthRecordFile :: write (const int numRec, const FixedLengthFieldsRecord & rec)
{
int positioning = seek (numRec);
if (positioning == RES_RECORD_DOESNT_EXIST || positioning == RES_ERROR)
return RES_ERROR;
char flag;
int res = fread(&flag,sizeof(flag),1,file);
if (res != 1) {
std::cout << "Couldn't read record flag of " << numRec << std::endl;
return RES_ERROR;
}
if (flag == 'O') // "occupied"
return RES_RECORD_EXISTS;
seek(numRec);
return rec.write(file);
}
int FixedLengthRecordFile :: read (int numRec, FixedLengthFieldsRecord & rec)
{
int positioning = seek (numRec);
if (positioning == RES_RECORD_DOESNT_EXIST)
return RES_RECORD_DOESNT_EXIST;
char flag;
int res = fread(&flag,sizeof(char),1,file);
if (res != 1) {
std::cout << "Couldn't read record flag of " << numRec << std::endl;
return RES_ERROR;
}
if (flag != 'O')
return RES_RECORD_DOESNT_EXIST;
return rec.read(file);
}
这是来自FixedLengthFieldsRecord
class ...
int FixedLengthFieldsRecord :: read (FILE* file)
{
int res = fread(&record,recordSize,1,file);
if (res != 1) {
std::cout << "Couldn't read record. " << std::endl;
return RES_ERROR;
}
std::cout << "Record read successfully! " << std::endl;
return RES_OK;
}
int FixedLengthFieldsRecord :: write (FILE* file) const
{
char flag = 'O';
int res = fwrite(&flag,sizeof(flag),1,file);
if (res != 1) {
std::cout << "Couldn't mark record as occupied. " << std::endl;
return RES_ERROR;
}
res = fwrite(&record,recordSize,1,file);
if (res != 1) {
std::cout << "Couldn't write record. " << std::endl;
return RES_ERROR;
}
std::cout << "Record written successfully! " << std::endl;
return RES_OK;
}
...这是valgrind
的输出:
X@notebook:~/Desktop/FixedRecordFile$ valgrind --leak-check=full --track-origins=yes --show-reachable=yes ./flrfile
Record written successfully!
==20368== Syscall param write(buf) points to uninitialised byte(s)
==20368== at 0x422A443: __write_nocancel (syscall-template.S:82)
==20368== by 0x41BCBA4: _IO_file_write@@GLIBC_2.1 (fileops.c:1289)
==20368== by 0x41BCA83: new_do_write (fileops.c:543)
==20368== by 0x41BE0FD: _IO_do_write@@GLIBC_2.1 (fileops.c:516)
==20368== by 0x8049DED: createFileAddRecordAndRead() (in /home/X/Desktop/FixedRecordFile/flrfile)
==20368== by 0x8049FE3: main (in /home/X/Desktop/FixedRecordFile/flrfile)
==20368== Address 0x4035021 is not stack'd, malloc'd or (recently) free'd
==20368== Uninitialised value was created by a stack allocation
==20368== at 0x8049C97: createFileAddRecordAndRead() (in /home/X/Desktop/FixedRecordFile/flrfile)
==20368==
File closed.
Record read successfully!
==20368== Invalid read of size 4
==20368== at 0x41B131C: fclose@@GLIBC_2.1 (iofclose.c:60)
==20368== by 0x8049F09: createFileAddRecordAndRead() (in /home/X/Desktop/FixedRecordFile/flrfile)
==20368== by 0x8049FE3: main (in /home/X/Desktop/FixedRecordFile/flrfile)
==20368== Address 0x8 is not stack'd, malloc'd or (recently) free'd
==20368==
==20368==
==20368== Process terminating with default action of signal 11 (SIGSEGV)
==20368== Access not within mapped region at address 0x8
==20368== at 0x41B131C: fclose@@GLIBC_2.1 (iofclose.c:60)
==20368== by 0x8049F09: createFileAddRecordAndRead() (in /home/X/Desktop/FixedRecordFile/flrfile)
==20368== by 0x8049FE3: main (in /home/X/Desktop/FixedRecordFile/flrfile)
==20368== If you believe this happened as a result of a stack
==20368== overflow in your program's main thread (unlikely but
==20368== possible), you can try to increase the size of the
==20368== main thread stack using the --main-stacksize= flag.
==20368== The main thread stack size used in this run was 8388608.
==20368==
==20368== HEAP SUMMARY:
==20368== in use at exit: 478 bytes in 5 blocks
==20368== total heap usage: 22 allocs, 17 frees, 1,112 bytes allocated
==20368==
==20368== 12 bytes in 1 blocks are still reachable in loss record 1 of 5
==20368== at 0x402A5E6: calloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==20368== by 0x8048D2E: FixedLengthFieldsRecord::FixedLengthFieldsRecord(int, int) (FixedLengthFieldsRecord.cpp:44)
==20368== by 0x8049CDF: createFileAddRecordAndRead() (in /home/X/Desktop/FixedRecordFile/flrfile)
==20368== by 0x8049FE3: main (in /home/X/Desktop/FixedRecordFile/flrfile)
==20368==
==20368== 12 bytes in 1 blocks are definitely lost in loss record 2 of 5
==20368== at 0x402A5E6: calloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==20368== by 0x8048D2E: FixedLengthFieldsRecord::FixedLengthFieldsRecord(int, int) (FixedLengthFieldsRecord.cpp:44)
==20368== by 0x8049E9D: createFileAddRecordAndRead() (in /home/X/Desktop/FixedRecordFile/flrfile)
==20368== by 0x8049FE3: main (in /home/X/Desktop/FixedRecordFile/flrfile)
==20368==
==20368== 51 bytes in 1 blocks are still reachable in loss record 3 of 5
==20368== at 0x402A5E6: calloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==20368== by 0x8048D14: FixedLengthFieldsRecord::FixedLengthFieldsRecord(int, int) (FixedLengthFieldsRecord.cpp:43)
==20368== by 0x8049CDF: createFileAddRecordAndRead() (in /home/X/Desktop/FixedRecordFile/flrfile)
==20368== by 0x8049FE3: main (in /home/X/Desktop/FixedRecordFile/flrfile)
==20368==
==20368== 51 bytes in 1 blocks are definitely lost in loss record 4 of 5
==20368== at 0x402A5E6: calloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==20368== by 0x8048D14: FixedLengthFieldsRecord::FixedLengthFieldsRecord(int, int) (FixedLengthFieldsRecord.cpp:43)
==20368== by 0x8049E9D: createFileAddRecordAndRead() (in /home/X/Desktop/FixedRecordFile/flrfile)
==20368== by 0x8049FE3: main (in /home/X/Desktop/FixedRecordFile/flrfile)
==20368==
==20368== 352 bytes in 1 blocks are still reachable in loss record 5 of 5
==20368== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==20368== by 0x41B1D17: __fopen_internal (iofopen.c:76)
==20368== by 0x8049E53: createFileAddRecordAndRead() (in /home/X/Desktop/FixedRecordFile/flrfile)
==20368== by 0x8049FE3: main (in /home/X/Desktop/FixedRecordFile/flrfile)
==20368==
==20368== LEAK SUMMARY:
==20368== definitely lost: 63 bytes in 2 blocks
==20368== indirectly lost: 0 bytes in 0 blocks
==20368== possibly lost: 0 bytes in 0 blocks
==20368== still reachable: 415 bytes in 3 blocks
==20368== suppressed: 0 bytes in 0 blocks
==20368==
==20368== For counts of detected and suppressed errors, rerun with: -v
==20368== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)
答案 0 :(得分:3)
您的错误在指针使用中。
res = fwrite(&record,recordSize,1,file);
应该是
res = fwrite(record,recordSize,1,file);
因为记录已经是指针。
类似地
int res = fread(&record,recordSize,1,file);
应该是
int res = fread(record,recordSize,1,file);
可能值得重命名该变量,因此很明显它是一个指针。在阅读代码时,我最初假设它是某种结构,所以我没有发现错误。