C++ 在类文件和缓冲区中查找段错误
这是我们的后续问题 我通过向类C++ 在类文件和缓冲区中查找段错误,c++,C++,这是我们的后续问题 我通过向类文件和缓冲区添加复制构造函数和赋值构造函数,修复了双重空闲和内存损坏。但远程服务器报告存在分段错误。是否有任何方法导致类文件或缓冲区段故障?我认为段故障通常与堆栈有关。但我在这两个类中没有堆栈操作 缓冲区 #ifndef __BUFFER_H__ #define __BUFFER_H__ #include <stdlib.h> #include <cerrno> #include <stdio.h> class Buffer
文件和缓冲区添加复制构造函数和赋值构造函数,修复了双重空闲和内存损坏。但远程服务器报告存在分段错误。是否有任何方法导致类文件
或缓冲区
段故障?我认为段故障通常与堆栈有关。但我在这两个类中没有堆栈操作
缓冲区
#ifndef __BUFFER_H__
#define __BUFFER_H__
#include <stdlib.h>
#include <cerrno>
#include <stdio.h>
class Buffer
{
private:
char * buffer;
int size;
Buffer(const Buffer &);
Buffer& operator=(const Buffer &);
public:
Buffer(int size);
~Buffer();
void reverse(int size);
friend class File;
};
#endif
bash脚本不是段错误的来源。我可以证实这一点。注意,测试服务可以提供许多不同版本的buggy main来测试文件
,缓冲区
和异常
,当使用无效参数调用时,崩溃的可能来源是读取
和写入
方法。例如,可以使用大小为10的缓冲区调用read
,但函数read
被请求读取20个字节。在这种情况下,缓冲区将溢出
您有两种解决方案:要么更改缓冲区类以便能够动态调整大小,要么读取/写入缓冲区的最大大小,例如:
tmp = fread(buffer.buffer, 1, min(size, buffer.size), this -> f);
对于写入
“我认为段故障通常与堆栈有关”-嗯,不是吗?你怎么会这么想?还有,你真的能重现这次坠机吗?(例如:测试您的实现的main
到底做了什么?)如果是,它发生在哪里?@UnholySheep我没有访问该服务器的权限。老实说,我不知道如何回答你的问题。我只知道它使用错误注入测试我的代码。它编译了各种主程序,包括我的文件、缓冲区和异常的实现。如果测试失败,它会给我一些错误信号。那个测试服务器把测试重点放在异常的行为上,但没有具体的指令告诉我到底什么是未测试的。@这是最难的部分。它非常盲目。我甚至不知道我的代码哪一行出错了。你确定你正确地初始化了构造函数中文件的位置吗?默认情况下是0吗?
#ifndef __FILE_H__
#define __FILE_H__
#include "Buffer.h"
#include "Exception.h"
#include <stdio.h>
#include <cerrno>
class File
{
private:
FILE * f;
File(const Buffer &);
File& operator=(const File &);
public:
int whence;
// Note: opening the same file twice for writing ("w")
// at the same time is forbidden
File(const char* name, const char *mode);
~File();
int read(Buffer& buffer, int size);
void write(Buffer& buffer, int size);
void seek(int pos);
void close();
// void seek(long offset, int whence);
long size();
};
#endif
#include "File.h"
File::File(const char* name, const char *mode)
{
f = fopen(name, mode);
if(f == NULL)
throw Exception(errno);
}
File::~File()
{
if(f != NULL)
fclose(f);
}
int File::read(Buffer& buffer, int size)
{
clearerr(this -> f);
size_t tmp;
tmp = fread(buffer.buffer, 1, size, this -> f);
// printf("%ld bytes read\n", tmp);
// for(int i = 0; i < tmp; i++)
// printf("%x ", buffer.buffer[i] & 0xff);
// printf("\n");
if(feof(this -> f) != 0)
return EOF;
if(ferror(this -> f) != 0)
throw Exception(errno);
return tmp;
}
void File::write(Buffer& buffer, int size)
{
size_t tmp;
clearerr(this -> f);
tmp = fwrite(buffer.buffer, 1, size, this -> f);
// printf("%ld bytes written\n", tmp);
// for(int i = 0; i < tmp; i++)
// printf("%x ", buffer.buffer[i] & 0xff);
// printf("\n");
if(ferror(this -> f) != 0)
throw Exception(errno);
}
void File::seek(int pos)
{
int ret = fseek(this -> f, pos, this -> whence);
if(ret != 0)
throw Exception(errno);
}
void File::close()
{
int tmp;
if(this -> f != NULL)
tmp = fclose(this -> f);
this -> f = NULL;
if(tmp != 0)
throw Exception(errno);
}
long File::size()
{
if(fseek(this -> f, 0, SEEK_END) != 0)
throw Exception(errno);
long tmp = ftell(this -> f);
if(tmp == -1)
throw Exception(errno);
if(fseek(this -> f, 0, SEEK_SET) != 0)
throw Exception(errno);
return tmp;
}
make: Entering directory `/home/vmcheck/testhome/co/rcopy'
g++ -c rcopy.cc
g++ -c Buffer.cc
g++ -c Exception.cc
g++ -c File.cc
g++ rcopy.o Buffer.o Exception.o File.o -o rcopy
make: Leaving directory `/home/vmcheck/testhome/co/rcopy'
======== COMPILING AGAINST OUR TESTS ========
g++ -c -Wall -I./ t1.cc -ot1.o
g++ -ot1 t1.o Buffer.o Exception.o File.o
g++ -c -Wall -I./ t2.cc -ot2.o
g++ -ot2 t2.o Buffer.o Exception.o File.o
g++ -c -Wall -I./ t3.cc -ot3.o
g++ -ot3 t3.o Buffer.o Exception.o File.o
g++ -c -Wall -I./ t4.cc -ot4.o
g++ -ot4 t4.o Buffer.o Exception.o File.o
g++ -c -Wall -I./ t5.cc -ot5.o
g++ -ot5 t5.o Buffer.o Exception.o File.o
g++ -c -Wall -I./ t6.cc -ot6.o
g++ -ot6 t6.o Buffer.o Exception.o File.o
g++ -c -Wall -I./ t7.cc -ot7.o
g++ -ot7 t7.o Buffer.o Exception.o File.o
g++ -c -Wall -I./ f1.cc -of1.o
gcc failed_read.c -ldl -shared -fPIC -o failed_read.so
gcc failed_write.c -ldl -shared -fPIC -o failed_write.so
failed_write.c:5:7: warning: conflicting types for built-in function ‘fwrite’ [enabled by default]
g++ -of1 f1.o Buffer.o Exception.o File.o
g++ -c -Wall -I./ f2.cc -of2.o
g++ -of2 f2.o Buffer.o Exception.o File.o
========= TESTING RCOPY ==========
Run: large file
size of input file: 16473
Run: small file
size of input file: 0
========= TESTING EXCEPTION BEHAVIOUR ==========
*** Test 1 ***
*** Test 2 ***
*** Test 3 ***
bash: line 1: 22041 Segmentation fault ./t3
FAILED
tmp = fread(buffer.buffer, 1, min(size, buffer.size), this -> f);