2016-11-15 7 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スタイルのキャストを使っているのはなぜですか? – UnholySheep

+3

確かに、ダブルフリーのリスクがあります。あなたはコピーコンストラクタを定義しませんでした。 [3つのルールは何ですか?](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three)についての記事を読んでください。それに加えて、 'malloc'と' new'の代わりに 'free'と、あなたのC++コードで' delete'をなぜ使用していますか? –

答えて

1

コンパイラが暗黙のコピーコンストラクタを生成することを許可されている場合、明示的にコピーを禁止し、バッファポインタを共有する2つのオブジェクトを介して空き領域を2倍にすることができます。さもなければ、私は二重自由が起こることができる方法を見ない。あなたはこのように、この中に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])を使用しない任意の理由は?

関連する問題