1

これはしばらくの間私を破壊してきました。これには理由があると確信しています。

chain operator+(chain c)
{
    chain<Object> result;
    for (int i = 0; i < length(); i++)
    {
        result.insert(*(Object*)(memory+(i*sizeof(Object))));
    }
    for (int i = 0; i < c.length(); i++)
    {
        result.insert(c[i]);
    }
    for (int i = 0; i < result.length(); i++) // This for loop successfully shows all objects in result
    {
        cout << result[i];
    }
    return result;
}

値が返されるとき、すなわち:

chain<int> a;
cin >> a; // enter "5 6 7 8"
chain<int> b;
cin >> b; // enter "9 10 11 12"
chain <int> c = a+b;

cout << c; // Returns "0 0 7 8 9 10 11 12"

最初の2つの数字は常に0です。理由がわかりません。これは、2つのチェーンを一緒に追加する場合にのみ発生します。aまたはbを計算すると、すべての値が得られます。

誰かが共有する情報を持っているなら、私は本当に感謝します:)

編集**

フルソース

#ifndef CHAIN_H
#define CHAIN_H

#include <iostream>
#include <stdlib.h>

using namespace std;

template <class Object>
class chain
{
    public:
            chain(){
                    memorySize = 8;
                    memory = calloc(memorySize, sizeof(Object));
                    count = 0;
            }
            chain(Object item){
                    memorySize = 8;
                    memory = calloc(memorySize, sizeof(Object));
                    count = 0;
                    insert(item);
            }
            chain(chain & original){
                    memorySize = 8;
                    memory = calloc(memorySize, sizeof(Object));
                    count = 0;
                    for (int i = 0; i < original.length(); i++)
                    {
                            insert(original[i]);
                    }
            }
            ~chain(){
                    free(memory);
            }
                chain operator+(chain c){
                    chain<Object> result;
                    for (int i = 0; i < length(); i++)
                    {
                            result.insert(this->operator[](i));
                    }
                    for (int i = 0; i < c.length(); i++)
                    {
                            result.insert(c[i]);
                    }
                    for (int i = 0; i < result.length(); i++)
                    {
                            cout << result[i];
                    }
                    return result;
            }
            Object & operator[](int pos){
                    return *(Object*)(memory+(pos*sizeof(Object)));
            }
            int length(){
                    return count;
            }
            void insert(Object item){
                    if (count == memorySize)
                    {
                            doubleMemory();
                    }
                    this->operator[](count) = item;
                    count++;
            }
    private:
            int count;
            int memorySize;
            void * memory;
            void doubleMemory(){
                    memorySize *= 2;
                    memory = realloc(memory, (memorySize*sizeof(Object)));
            }

};
template <class Object>
ostream& operator<<(ostream& out, chain<Object>& c){
    for (int i = 0; i < c.length(); i++)
    {
            out << c[i] << " ";
    }
}
template <class Object>
istream& operator>>(istream& in, chain<Object>& c){
    char ch;
    int number = 0;
    int sign;
    while(ch != '\n')
    {
            ch = in.get();
            if (ch == '-')
            {
                    sign = 1;
            }
            else if (ch >= '0' && ch <= '9')
            {
                    number *= 10;
                    number += (ch-48);
            }
            else if (ch == ' ' || ch == '\n')
            {
                    number = sign == 1? 0 - number : number;
                    c.insert(number);
                    sign = 0;
                    number = 0;
            }
    }
}
#endif

これが私がテストしているコードです:

#include "chain.h"

using namespace std;

int main(){

    chain<int> a, b, c;
    chain<int> d(10);
    chain<int> e(d);
    cin >> a;
    cout << endl;
    cout << endl;
    c = a+d;
    cout << c;
}

4

2 に答える 2

3

あなたが示したコードは問題ではありません。実際の問題は、おそらくコピー コンストラクターまたはデストラクタのいずれかにありchain 、insertメソッド (または、C++11 ではムーブ コンストラクター) にもある可能性があります。

(Objectのコピー コンストラクターにも含まれている可能性がありますが、その可能性は低いと思います。)


編集:ああ、私。そのようなコードを C++ で記述しないでください。左、右、中央が危険です。POD である限りObjectは問題ありませんが、そうでない場合、このコードは未定義の動作を引き起こします。特に、チェーンに格納するオブジェクトの適切なコンストラクターとデストラクタを呼び出しません。

chain const&さらに、渡された を変更していないため、コピー コンストラクターは型の引数を取る必要がありますchainconstこれには、 の適切なオーバーロードを提供して、クラス const を正しくする必要がありますoperator []

最後に、そして最も明白なことですが、あなたは を実装していないため、3 つのルールに違反していoperator =ますchain。1 つを別のものに割り当てようとすると、chain結果的に 2 つの解放が発生します。

一般に、代わりに標準コンテナーを使用することを避けcallocfree使用するか、それがオプションでない場合は、boost::shared_arraynew[]などのスマート ポインターを使用してメモリを管理します (ただし、使用しないでください)。delete[]

もう 1 つusing namespace、ヘッダー ファイルで使用しないでください。名前空間が汚染され、最も奇妙な場所で名前の競合が発生します。

于 2012-09-11T09:03:34.590 に答える
0

さて、コピーコンストラクタに関して次の問題があります。これをコピーコンストラクターとして機能させたいようです:

chain(chain & original){
    memorySize = 8;
    memory = calloc(memorySize, sizeof(Object));
    count = 0;
    for (int i = 0; i < original.length(); i++)
    {
        insert(original[i]);
    }
}

しかし、メソッドの宣言が間違っているため、それはできません。copy 引数に const 修飾子がありません。含めない場合、コンパイラは、変更可能な参照で動作する通常のコンストラクターのみを宣言していると見なし、これは Rule of Threeに従って定義する必要があるコピー コンストラクターではありません。

これを変更するだけです:

chain(chain & original){

これに:

chain(const chain & original){

これにより、おそらく間違ったメモリ処理が解決され、プログラムで異なる出力が得られることを願っています。

于 2012-09-11T09:50:11.600 に答える