2

配列を返さなければならない関数を書くなどの一般的なタスクを手伝ってください。この問題の解決に 2 時間費やしましたが、結果は得られませんでした。これが私のコードです:

 VERTEX* ConstructVertices(float R, unsigned int Slices)
{
    //const unsigned int n = static_cast<const unsigned int>(Slices);
    VERTEX *__vertices = new VERTEX[100];

    float dx = (2 * R) / Slices;
    float dz = dx;
    float x, y, z;
    x = -R;
    y = 0.5f;
    z = 0;
    int x_sign = 1;
    int z_sign = -1;

    __vertices[0].Color = D3DXCOLOR(0.0f, 1.0f, 0.0f, 1.0f);
    __vertices[0].Pos = D3DXVECTOR3(x, y, z);

    for (int i=1; i<Slices * 4 + 1; i++)
    {
        __vertices[i].Color = D3DXCOLOR(0.0f, 1.0f, 0.0f, 1.0f);

        y = -y;

        if (y < 0)
        {
            __vertices[i].Pos = D3DXVECTOR3(x, y, z);
            continue;
        }

        x += x_sign * dx;
        z += z_sign * dz;

        x = round_up(x, 2);
        z = round_up(z, 2);

        if (abs(x) == abs(R))
        {
            x_sign = -x_sign;
        }
        if (abs(z) == abs(R))
        {
            z_sign = -z_sign;
        }

        __vertices[i].Pos = D3DXVECTOR3(x, y, z);   
    }

    return __vertices;
}

配列にアクセスするためのコード:

VERTEX *vertices = new VERTEX[100];
vertices = ConstructVertices(1, 10);

Watchesウィンドウでは、頂点[0]、頂点[1]、..のような値を見ることができますが、配列として見ることはできません。メインはsizeof(頂点)が160ではなく4を返します!!

どうもありがとうございます!

4

4 に答える 4

1

コードでは、最初にメモリを動的に割り当てます。

VERTEX *vertices = new VERTEX[100];
vertices = ConstructVertices(1, 10);

そして、関数で新しいメモリを割り当てます。

//const unsigned int n = static_cast<const unsigned int>(Slices);
VERTEX *__vertices = new VERTEX[100];

そして最後に、このポインターを返し、作成した最初のポインターを置き換えます。メモリは2回割り当てられます。

于 2012-12-15T18:51:29.437 に答える
1

を返すだけstd::vector<VERTEX>です。

ヒープに割り当てられたメモリへのポインターを返すには、いくつかの大きな問題があります。

  1. 適切に処理しないと、メモリが簡単にリークする可能性があります。
  2. インターフェイスからは、メモリを解放する方法が明確ではなく、コンパイラは正しいアプローチを使用するのを助けることができません (ただし、使用delete[] a;は正しいアプローチが何であるかを推測する可能性があります)。
  3. ポインタから返された配列のサイズを決定することはできません。

明らかに、適切な操作を提供するクラスを作成できますが、これが実際のものstd::vector<T>です。&a[0]要素へのポインタが必要な場合は、空でないベクトル ( ) またはの最初の要素のアドレスを使用してくださいa.data()。後者は C++ 2011 で導入されたもので、空の配列でも動作するという大きな利点があります (もちろん、返されたポインターを逆参照することはできません)。

于 2012-12-15T18:50:28.220 に答える
0

「メインはsizeof(vertices)が160ではなく4を返します!!」これは、頂点がポインターであり、明らかにハイテクの32ビットコンピューターを使用しているため、ポインターのサイズは4バイトです。
もう1つのポイントは次のとおりです。

VERTEX *vertices = new VERTEX[100];
vertices = ConstructVertices(1, 10);

最初の割り当ては役に立たない。なぜなら、これまで使用されたビーイングなしで2番目の割り当てによって上書きされるため、100VERTEXでメモリをリークするだけだからです。

于 2012-12-15T18:51:07.737 に答える
0

これの代わりに

VERTEX *vertices = new VERTEX[100];
vertices = ConstructVertices(1, 10);

頂点配列を引数として関数に追加し、関数にサイズを伝えます

VERTEX *vertices = new VERTEX[100];
ConstructVertices(1, 10,vertices,100);

次に、関数内で渡された配列を埋めます

void ConstructVertices(float R, 
                       unsigned int Slices,
                       VERTEX* vertices, 
                       size_t verticesArraySz )
{
    //const unsigned int n = static_cast<const unsigned int>(Slices);

    float dx = (2 * R) / Slices;
    float dz = dx;

...

のような名前を使用しないでください__vertices。通常、コンパイラ固有のものはその構文を使用するため、これは良い習慣ではありません。

于 2012-12-15T19:54:41.520 に答える