1

realloc がポインターを返さなくなるポイントに到達しました。配列を拡張または移動するためのスペースが不足していると思います。唯一の問題は、そのメモリが存在する必要があるか、アプリケーションが期待どおりに実行できないことです。そのため、malloc を試すことにしました。なんで?

次に、ポインターの配列を新しく割り当てられた配列にmemcpyしましたが、それが壊れていることがわかりました.0x10や0x2bなどのポインターが配列に入れられました。実際のポインターはありますが、memcpy を for ループに置き換えると修正されます。なぜmemcpyはそれをしたのですか?コードで memcpy を使用すべきではありませんか?

コード:

float * resizeArray_by(float *array, uint size)
{
    float *tmpArray = NULL;
    if (!array)
    {
        tmpArray = (float *)malloc(size);
    }
    else
    {
        tmpArray = (float *)realloc((void *)array, size);
    }

    if (!tmpArray)
    {
        tmpArray = (float *)malloc(size);
        if (tmpArray)
        {
            //memcpy(tmpArray, array, size - 1);
            for (int k = 0; k < size - 1; k++)
            {
                ((float**)tmpArray)[k] = ((float **)array)[k];
            }
            free(array);
        }
    }

    return tmpArray;
}

void incrementArray_andPosition(float **& array, uint &total, uint &position)
{
    uint prevTotal = total;
    float *tmpArray = NULL;
    position++;
    if (position >= total)
    {
        total = position;
        float *tmpArray = resizeArray_by((float *)array, total);
        if (tmpArray)
        {
            array = (float **)tmpArray;

            array[position - 1] = NULL;
        }
        else
        {
            position--;
            total = prevTotal;
        }
    }
}

void addArray_toArray_atPosition(float *add, uint size, float **& array, uint &total, uint &position)
{
    uint prevPosition = position;
    incrementArray_andPosition(array, total, position);

    if (position != prevPosition)
    {
        float *tmpArray = NULL;
        if (!array[position - 1] || mHasLengthChanged)
        {
            tmpArray = resizeArray_by(array[position - 1], size);
        }

        if (tmpArray)
        {
            memcpy(tmpArray, add, size);
            array[position - 1] = tmpArray;
        }
    }
}

すべての修正の後、コードはおそらく初期化されます。ここで興味深いのは、配列を並べ替えた後、malloc を使用して巨大な配列を割り当て、配列を 1 つの配列に並べ替えて GL_ARRAY_BUFFER として使用することです。スペース不足のために realloc が割り当てられていない場合、なぜ割り当てられないのでしょうか?

最後に、これにより最終的にクラッシュします。クラッシュしたらレンダリング機能を通過した後。すべての修正を削除し、realloc が割り当てられないときにキャッチした場合、問題なく動作します。これは疑問を投げかけます.私の配列を再割り当てする代わりにmallocすることの何が問題なのですか?

私の配列は、フロートのポインターのポインターです。配列を大きくすると、浮動小数点数へのポインターに変換され、再割り当てされます。私は Android でビルドしているため、メモリが不足していると想定しました。

4

3 に答える 3

3

さまざまな情報 (reallocメモリが見つからmemcpyない、予期しない動作、クラッシュ) から判断すると、これはヒープの破損のように思えます。正確に何をしているのかを示すいくつかのコード サンプルがないと、確実に言うのは難しいですが、ある時点でメモリの管理を誤っており、ヒープが無効な状態になっているようです。

Linux などの代替プラットフォームでコードをコンパイルできますか (一部の Android 固有の API をスタブする必要がある場合があります)。もしそうなら、そのプラットフォームで何が起こっているかを確認したり、valgrind を使用して追跡したりできます。

最後に、このタグ付けされた C++ があるのに、たとえばvector(または別の標準コンテナー) または の代わりに malloc/realloc を使用するのはなぜnewですか?

于 2011-05-10T14:42:13.353 に答える
1

あなたは紛らわしいsizeポインタ型です。メモリ割り当てでsizeは、 はバイト数であり、ポインター型を に変換し、基本的にサイズfloat *の配列を作成します。memcpy に相当するコードでは、配列をコピーしてコピーしています。これにより、ヒープが破棄され、後で問題が発生する可能性が高くなります。floatsize / sizeof(float)float **sizesizeof(float *) > 1

さらに、たとえば 100 サイズの配列を 200 サイズの配列にコピーする場合、200 ではなく 100 を超える要素をコピーする必要があります。クラッシュをプログラムする。

動的に割り当てられたfloatsへのポインターの配列はfloat **、 ではなくfloat *であり、2 つの混合でもありません。配列のサイズは、malloc とフレンズのバイト数、およびすべての配列操作の要素数です。

memcpyコピー元とコピー先のブロックが重複しない (そして個別に割り当てられたメモリ ブロックが重複しない) と仮定して、バイトを忠実にコピーします。size - 1ただし、コピーされたバイト数が古い配列の正確なバイトサイズである必要がある場合、コピーされたバイト数を指定しました。(とにかく、どこで悪いポインター値を取得していますか?それが配列の拡張部分にある場合は、とにかくそこにガベージをコピーしています。)memcpyがナンセンスを与えている場合、それはそもそもナンセンスになっており、それはあなたの問題ではありません.

于 2011-05-10T15:40:19.197 に答える
0

ところで、テストする必要はありませarrayNULL

交換できます

if (!array)
{
    tmpArray = (float *)malloc(size);
}
else
{
    tmpArray = (float *)realloc((void *)array, size);
}

tmpArray = realloc(array, size*sizeof (float));

reallocポインタmallocが与えられたときのように動作します。NULL

もう1つ、サイズが0ではないことに注意してください。サイズが0の場合は、と同じ freeです。

3 番目のポイントは、厳密に必要でない場合はポインターを型キャストしないことです。割り当て関数の戻り値を型キャストしました。ANSI-C 以降、これは悪い習慣と見なされています。これは C++ では必須ですが、C 割り当てを使用しているため、明らかに C++ ではありません (その場合はnew/を使用する必要がありますdelete)。配列変数を (void *) にキャストすることも不要です。パラメーターが誤って宣言された場合にいくつかの警告を非表示にする可能性があるためです (int またはポインターへのポインターである可能性があり、キャストすることで警告が抑制されます)。

于 2011-05-10T17:07:57.593 に答える