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);