0
#define ARRAY_SIZE 20

float DataSource[ARRAY_SIZE];

void Read(unsigned char const *Source, unsigned char *Destination, unsigned long DataSize)
{
  for ( unsigned long i = 0; i < DataSize; i++)
  {
    *(Destination + i*DataSize) = *(Source + i*DataSize);
  }
}

void fun()
{
  int Index;
  float Dest;

  for ( Index = 0; Index < ARRAY_SIZE; Index++ )
  {
    Read((unsigned char *)&DataSource[Index], (unsigned char *)&Dest, sizeof(DataSource[Index]));
  }
}

上記のコードに問題があり、Read()を呼び出すと、Index変数が上書きされ、醜いポインターのキャストが原因であると確信していますが、ここで何が起こっているのかを正確に理解するのに問題があります。

上記のコードは、一部のドライバーレベルのソフトウェアをシミュレートし、同じプロトタイプを維持することを目的としているため、unsignedcharポインター型は必須です。

誰かが私がここで問題を理解するのを手伝ってもらえますか?上記のコードはすべて、Read()のプロトタイプを除いて変更可能です。

4

6 に答える 6

4

エラーはここにあります:

for ( unsigned long i = 0; i < DataSize; i++)
{
  //              vvvvvvvvvv               vvvvvvvvvv
  *(Destination + i*DataSize) = *(Source + i*DataSize);
}

i * DataSizei常に=>「範囲外」アクセスより大きい。

と置換する:

for ( unsigned long i = 0; i < DataSize; i++)
{
  *(Destination + i) = *(Source + i);
}
于 2013-01-10T22:12:20.593 に答える
2

単一floatのアドレスをRead&Dest)に渡してから、連続するメモリ位置に多くの値を書き込みます。indexその時点でランダムメモリを書き込んでいるので、スタックは通常下向きに大きくなるため、上書き(およびその他のもの)される可能性はほとんどありません。

于 2013-01-10T22:12:39.697 に答える
1

これは間違っています:

*(Destination + i*DataSize) = *(Source + i*DataSize);

DataSizeバイト間隔ではなく、隣接するバイトをコピーするDataSize(合計スパンDataSize*DataSize

言うだけ

Destination[i] = Source[i];
于 2013-01-10T22:12:55.017 に答える
1

(私にとって)面白いC++の方法。

template<typename Data>
struct MemBlockRefHelper {
  typedef Data value_type;
  Data* data;
  size_t size;
  MemBlockRefHelper( Data* d, size_t s):data(d), size(s) {}

  template<typename Target, typename Other=typename Target::value_type>
  Target& Assign( MemBlockRefHelper<Other> const& other ) {
    Assert(size == other.size);
    for (size_t i = 0; i < size; ++i) {
      if (i < other.size) {
        data[i] = other.data[i];
      } else {
        data[i] = 0;
      }
    }
    Target* self = static_cast<Target*>(this);
    return *self;
  }

};
struct MemBlockRef;
struct MemBlockCRef:MemBlockRefHelper<const unsigned char> {
  MemBlockCRef( const unsigned char* d, size_t s ):MemBlockRefHelper<const unsigned char>( d, s ) {}
  MemBlockCRef( const MemBlockRef& other );
};
struct MemBlockRef:MemBlockRefHelper<unsigned char> {
  MemBlockRef( unsigned char* d, size_t s ):MemBlockRefHelper<unsigned char>( d, s ) {}
  MemBlockRef& operator=( MemBlockRef const& other ) {
    return Assign< MemBlockRef >( other );
  }
  MemBlockRef& operator=( MemBlockCRef const& other ) {
    return Assign< MemBlockRef, const unsigned char >( other );
  }
};
inline MemBlockCRef::MemBlockCRef( const MemBlockRef& other ): MemBlockRefHelper<const unsigned char>( other.data, other.size ) {}

void Read( unsigned char const* Source, unsigned char* Dest, unsigned long DataSize ) {
  MemBlockCRef src( Source, DataSize );
  MemBlockRef dest( Dest, DataSize );
  dest = src;
}

大幅に過剰設計されていますが、アイデアは、特定のサイズのPODメモリのブロックのアイデアをまとめ、そのコンテンツへの参照セマンティクスを提供することです(初期化は同じデータへの新しい参照を作成し、割り当ては参照されたものをコピーしますデータへ)。

このようなクラスを作成すると、のコードReadは3ライナーになります。まあ、あなたは1つでそれを行うことができます:

  MemBlockRef( Dest, DataSize ) = MemBlockCRef( Source, DataSize );

しかし、それは不必要です。

さて、それはこのフレームワーク全体です。

しかし、私はそれを書くことで面白がっていました。

于 2013-01-10T22:28:20.357 に答える
0

あなたのRead():iを0からDataSize-1に変更します。i * DataSize ...のオフセット、つまり0からDataSize *(DataSize-1)までのオフセットでメモリにアクセスするたび。DataSize**2-DataSize意味がないので、間違って見えます。

他の答えとは異なり、私はあなたが何を望んでいたかを推測したくありません。作者の心を読まに、コードの最も間違った部分を見つけるのに役立つ一種の「次元分析」を示すだけです。

于 2013-01-10T22:15:16.883 に答える
0

Dest内部で宣言されたスカラー変数を内部fun()の配列として扱っていますRead()DestIndex変数の両方がスタック上で隣接して配置されているようです。これは、内部のループが実行されIndexたときに正確に上書きされることを説明しています。Read()i==1

したがって、解決策は次のとおりです。Dest配列として宣言することもできます。

float Dest[ARRAY_SIZE];
于 2013-01-10T22:32:26.613 に答える