2012-03-29 3 views
-1

私はstd :: vectorを配列の代わりにC++で使用することができ、しかし、この質問は実用的なものではありません。それは私の理解のためです。私はmemcpy()操作の実際の値の代わりに '0'を参照してください。このテストコードで何が間違っていますか?コンストラクタの整数配列に対するmemcpy()操作は、C++で予期せぬ出力を与えます

#include <stdint.h> 
#include <cstring> 
#include <cstdlib> 
#include <iostream> 

using namespace std; 

class IntList 
{ 
private: 
    int* m_anList; //I could use std::vector in practical applications I know 
        //However I want to experiment what happens 

public: 
     IntList(const int m_anList[]){ 
     this->m_anList = new int[sizeof(m_anList+1)]; //heap allocation - since bad idea to copy on stack 

     memcpy((int*)this->m_anList,m_anList,sizeof(m_anList+1)); //<-This does not look right 
     cout << this->m_anList[4] << endl;//<- gives '0'??? Not expected 

     } 
    ~IntList(){ 
     if(this->m_anList) 
     { 
     delete[] this->m_anList; 
     } 
    } 

    int& operator[] (const int& nIndex); 
}; 

int& IntList::operator[] (const int& nIndex) 
{ 
    cout << this->m_anList[nIndex] << endl; //<- gives '0'??? Not Expected 
    return this->m_anList[nIndex]; 
} 


int main() 
{ 

    int test_array[10] = {1,2,3,4,5,6,7,8,9}; 

    IntList test(test_array); 

    test[2];  

    return 0; 
} 

私はこれを以前char *で使用していました。 char = 1 Byte、int = 2 Byteではなくmemcpyがvoid *に適用されます。

更新されたコード/ソリューション(ロブのおかげで(いくつかのミスの私の最も基本的なことを指摘WHO)と答えたみんな。私はCS卒業生はないですが、将来的にはより良いコードしようとするだろう。おかげで再び。)

#include <stdint.h> 
#include <cstring> 
#include <cstdlib> 
#include <iostream> 
//#include <algorithm> 
//#include <vector> 

using namespace std; 

class IntList 
{ 
private: 
    int* m_anList; //I could use std::vector in practical applications I know 
        //However I want to experiment what happens 

public: 
     IntList(const int m_anList[], std::size_t n){ 
     this->m_anList = new int[n * sizeof(int)]; 
     memcpy(this->m_anList,m_anList,n*sizeof(m_anList[0])); 
     cout << this->m_anList[4] << endl;  
    } 
    ~IntList(){ 
     if(this->m_anList) 
     delete[] this->m_anList; 
    } 

    int& operator[] (const int& nIndex); 
}; 

int& IntList::operator[] (const int& nIndex) 
{ 
    cout << this->m_anList[nIndex] << endl; 
    return this->m_anList[nIndex]; 
} 


int main() 
{ 

    int hello[10] = {1,2,3,4,5,6,7,8,9}; 

    //cout << hello[3] << endl; 

    IntList test(hello,10); 

    test[2]; 


return 0; 
} 
+2

あなたがこれから学ぶことができる最高のことは、うまく行かなかった不吉なことをするように導いたことです。あなたの将来の同僚を検討してください。彼らは生の配列とmemcpuでそれらをさせる場合、彼らは同じ方法を汚すでしょう。 –

+1

'sizeof(m_anList + 1)'は何になると思いますか? "* int = 2 Byte *"過去15年間の主要なプラットフォームではありません... – ildjarn

+0

あなたの質問には関係ありませんが、メンバ関数のパラメータにメンバー変数(m_anList)と同じ名前を付けることは災害のレシピです。 –

答えて

4

sizeof(m_anList+1)あなたはそう思わないと思います。特に、sizeof(int*)と同じです。その結果、渡された配列のサイズではなく、new式に(通常)4バイトまたは8バイトしか割り当てられません。

、この作業を行うために、あなたはまた、配列のサイズを渡す必要があります:newに割り当てられた

IntList(const int m_anList[], std::size_t n){ 
    this->m_anList = new int[n]; 
    memcpy(this->m_anList,m_anList,n*sizeof(m_anList[0])); 
    … 
+0

私はG ++コンパイラで動作させるためにsizeof(int)の前後に括弧を追加するだけでした:)。 – enthusiasticgeek

+0

@enthusiasticgeek - 申し訳ありません。私のコードはテストされておらず、エラーが見つかりました。私は今それを修正しています。 –

+0

あなたの投稿を編集する権限がまだありませんので、コメントを残しました。再度、感謝します。 – enthusiasticgeek

0

メモリは、独自のサイズを覚えていません。あなたはそれを独自の整数で側に保ち、THATを使ってメモリを割り当ててコピーする必要があります。 sizeof式はポインタのバイト数を取得します。

メモリのリークを避けるために、コピーの作成と割り当てを実装/無効にしてください。

生産コードではvectorを使用してください。すべてこれらの問題が発生します。 C++で

1

「配列構文」

void foo(int v[]) 
{ 
    ... 
} 

を使用してパラメータを受け取る関数を宣言しますが、実際にちょうどポインタを受け取る関数を宣言しています。上記すなわち は、ポインタではなく、アレイのサイズの大きさである

void foo(int *v) 
{ 
    ... 
} 

sizeof(v)と全く同じです。

コンパイラを試してみて、C++を学ぼうとするのを止めてください。 C++言語では、このようなアプローチは完全な自殺です。

代わりにa good C++ bookで始まり、それをカバーするように読む...それは唯一の方法です。

+0

ありがとうございました6502.私はScott Meyersの著書「Effective C++」と「Andrei Alexandrescu Modern C++ design」から学んでいます。私はC++で初心者だと思う。しかし、私はCS卒業生ではないので、私のコードから分かるように、私はコーディングの実験をしています。 – enthusiasticgeek

+0

マイヤー効果的なC++とより効果的なC++は私の意見では非常に良いです。しかしIMOでも、Stroustrup TCPPPLのような基本的な完全な説明を読むべきです。近代的なC++の設計については、著者が非常に優れていると確信していますが、アイデアの一部はアイ・オープナーです...しかし、テンプレート・マシン全体はナンセンスの悪用レベルに陥る可能性があり、現実の世界よりも無意味なトリッキーなエクササイズツール。高度なメタプログラミングは、C + +ではなく、非常に強力で素敵な武器です。 – 6502

0

あなたはsizeof()の外に+1を置くべきです。

+0

ありがとう+1これ私はそれを逃した。 – enthusiasticgeek

+0

@enthusiasticgeek:それはちょうど別の問題を引き起こす根本的な問題を解決しません。 – Blastfurnace

2

  • Cスタイルはmemcpy代わりのstd::copy

ありませんを使用して

  • sizeofポインタ

  • をキャスト含め、非常に多くの間違ったコードにあります単一の修正が可能です。

  • +0

    std :: copyは意味しません。を含める必要がありますか? – enthusiasticgeek