0

要素を 1 スポット右memmoveにシフトするために使用しています。std::string目的地の最初のスポットは、めちゃくちゃでゴミだらけの唯一のスポットです。テンプレートを必要とするクラスで使用しているため、memmove代わりに使用しています。strcpyただし、intの配列がある場合は正常に機能します。文字列に対してこれを修正する方法について何か考えはありますか?

/**
 * @brief Shifts elements in the array to the right
 * @param newItem The insert position.
 */
template<class T>
void DynamicArray<T>::shiftElementsRight(uint newItem) {
    uint diff = _size - newItem;
    memmove(&(_array[newItem + 1]),
            &(_array[newItem]), sizeof(_array[0]) * diff);
}

マイメイン

int main() {
    DynamicArray<string> array(1);

    string val1 = "val1";
    array.add(val1);
    string val2 = "val2";
    array.add(val2);
    // ... more additions ...

最後の出力:

Sizeof: 8
Value is: val1
Value is: val11val3, val21
                            ����[val1, val2A����[val1, val2, val31val4, Aq�����[val1, val2, val3 val4, val5Q`r�#����[val1, val2, val3, val4, val5, val61val5, 1val6, Q"����[val1, val2, val3, al4, a
8s��p�hp��p�hq�(r�Xr�؄KC�؄KC�؄KC�1val7, a:����[val1, val2, val3, val4, val5, qF����[val1, val2, val3, val4, val5, val6]
4

5 に答える 5

6

配列にオブジェクトが含まれている場合は、どちらmemcpyも可能ではありません。その理由は、どちらもオブジェクトの内部を改ざんしてはならないときに改ざんするためです (C++ オブジェクトの整合性は、コンストラクター/代入演算子/デストラクタ/メンバー関数によって保証されます。正確に何を知っていない限り、バイトを手動で変更してはなりません)。行う)。memmovestd::string

すでに提案されているように、コンストラクタ、代入演算子、およびデストラクタを考慮に入れるメソッドを使用するstd::copy_backwardか (たとえば)、さらに良いことに、それらのレガシー C 配列を取り除き、適切な C++ コンテナーvectorを使用し、コンテナーの関数を使用してアイテムを挿入/削除します。

つまり、C++ オブジェクトを使い始めるとすぐに、"C with classes" ではなく、C++ を書き始める必要があります。

于 2013-10-18T07:37:08.400 に答える
1

ここのほとんどの人が言うように、重複する範囲を処理できるため、memmove代わりに使用できます。memcpy

ただし、C++ の解決策は を使用することcopy_backwardです。これは、要求したことを明示的に実行し、画面の背後で最速のコピー方法を選択します。それは次のようになります。

std::copy_backward(std::begin(_array)+newItem, std::end(_array)-1, std::end(array));

これは、最後から前の要素から newItem の位置まで逆方向にコピーし、その後ろから挿入することを意味します。これは明らかに、これが必要とするオーバーラップを処理できます。画面の背後で memmove またはその他のプラットフォーム固有のメモリ コピーが使用されている可能性があります。

于 2013-10-18T07:23:23.747 に答える