2016-11-15 28 views
0

我编写了一个简单的Buffer类,它包含一个缓冲区并提供了一个函数来反转缓冲区的内容。在这个类中是否有任何双重风险

Buffer.h

#ifndef __BUFFER_H__ 
#define __BUFFER_H__ 

#include <stdlib.h> 
#include <cerrno> 
#include <stdio.h> 

class Buffer 
{ 

private: 
    char * buffer; 
    int size; 


public: 
    Buffer(int size); 
    ~Buffer(); 
    void reverse(int size); 

}; 

#endif 

Buffer.cc

#include "Buffer.h" 


Buffer::Buffer(int size) 
{ 
    this -> size = size; 
    this -> buffer = (char *)malloc(size); 
    if(this -> buffer == NULL) 
    throw 1; 
} 

Buffer::~Buffer() 
{ 
    if(this -> buffer != NULL) 
    free(this -> buffer); 
} 

void Buffer::reverse(int size) 
{ 
    char tmp; 
    int i; 
    char * tmpb = this -> buffer; 
    for(i = 0; i < size/2; i++) 
    { 
    tmp = (char)tmpb[i]; 
    tmpb[i] = tmpb[size - i - 1]; 
    // printf("exchange %x with %x\n", tmp & 0xff, tmpb[i] & 0xff); 

    tmpb[size - i - 1] = tmp; 
    } 
} 

有一个远程服务器使用故障注入来测试我的实现。该服务器给我报告说有双重空闲或腐败引起的错误。我已经多次阅读我的实现,但没有找到该错误的运气。我没有访问该服务器。任何帮助?我不得不使用C风格的代码。否则,我会失败的服务器测试。这是一个很难的要求。那么,你可能会认为这个要求很愚蠢。但这是要求。也许有一点是在混合C和C++的时候学习坏的。

服务器提供了一个主函数来测试我的实现。

对于任何想要查看所有代码的人,可以从https://mega.nz/#!FhoHQD5Y!iD9tIZMNtKPpxfZTpL2KWoUJRedbw6wToh6QfVvzOjU下载zip文件。只需使用make进行编译。其结果是名为的程序,该程序逐字节地反转文件的内容,然后输出到新文件。

+2

这是应该做什么,'std :: vector'与'std :: reverse'完成不了吗? –

+1

不完全相关,但为什么在C++代码中使用'malloc','free'和C-style转换? – UnholySheep

+3

确实存在双重的免费风险。你没有定义复制构造函数。阅读有关[什么是三条规则?](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-ree)。除此之外,为什么你在你的C++代码中使用'malloc','free'而不是'new'和'delete'? –

回答

1

考虑禁止显式复制,如果允许编译器生成隐式拷贝构造函数,那么它可以通过共享缓冲区指针的两个对象释放两次。否则,我认为不可能发生双重自由。为此,您可以在C++ 11这样的:

class Buffer { 
private: 
    char *buffer; 
    int size; 

public: 
    Buffer(int size); 
    Buffer(const Buffer &) = delete; 
    Buffer &operator=Buffer(const Buffer &) = delete; 
    ~Buffer(); 
    void reverse(int size); 

}; 

一些小笔记:

1.

free(NULL)由标准定义为一个无操作。所以

if(this -> buffer != NULL) 
    free(this -> buffer); 

可以只是:

free(this -> buffer); 

2.

tmp = (char)tmpb[i]; 

为什么在这里投? tmpb[i]应该已经是char。作为一般的经验法则,大多数时候你觉得需要投射,这可能意味着有更好的方法来完成这项任务。当然也有例外,但干净的代码应该具有最少的投射。

3.

任何理由不只是使用std::swap(tmpb[size - i - 1], tmpb[i])你的反向功能里面?

相关问题