0

realloc を使用してヒープ上の int の配列を拡張しようとしていますが、カスタム関数 "ExpandArrayOfInts" を使用するとプログラムがクラッシュしますが、main 内に拡張コードを記述すると正常に動作します。

両方のアプローチの #defines を使用したコード (ファイル: main.c) を次に示します。

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

int ExpandArrayOfInts(int* arrayToExpand, int expandBy, int inArraySize, int* outArraySize);


int main (int argc, char** argv)
{
#if 1//CODE THAT WORKS

int arraySize = 10;
int* arrayDnmc = NULL;
int* arrayDnmcExpndd;


for (int i = 0; i< 10; ++i)
{
    arrayDnmcExpndd = (int*)realloc(arrayDnmc, (arraySize + (i * 10)) * sizeof(int));
    if (arrayDnmcExpndd != NULL)
    {
        arrayDnmc = arrayDnmcExpndd;
        memset(arrayDnmc, 0, (arraySize + (i * 10)) * sizeof(int));
    }
    else
    {
        printf("Failed to (re)alloc memory for arrayDnmc!\n");
        free(arrayDnmc);
        return -1;
    }
}
free(arrayDnmc);

#else   //CODE THAT DOESN'T WORK (Which I'm trying to make it work)

int maxSize = 100;
int arraySize = 10;
int* arrayDnmc = NULL;

arrayDnmc = (int*)malloc(arraySize * sizeof(int));
if (arrayDnmc != NULL)
{
    memset(arrayDnmc, 0, arraySize * sizeof(int));
}
else
{
    printf("malloc failure!\n");
    return -1;
}

while (arraySize < maxSize)
{
    if (0 != ExpandArrayOfInts(arrayDnmc, 5, arraySize, &arraySize))
    {
        printf("Something went wrong.\n");
        break;
    }
    //do something with the new array
    printf("new size: %i\n", arraySize);
}
free(arrayDnmc);
#endif
return 0;
}

int ExpandArrayOfInts(int* arrayToExpand, int expandBy, int inArraySize, int* outArraySize)
{
int newSize = inArraySize + expandBy;
int* arrayTemp = (int*)realloc(arrayToExpand, newSize * sizeof(int));
if (arrayTemp != NULL)
    {
        arrayToExpand = arrayTemp;
        *outArraySize = newSize;
        return 0;
    }
    return -1;
}

機能しない部分では、次の出力が得られます。

新サイズ:15
新サイズ:20

そして、クラッシュメッセージが表示されます:

「Windows が c_cplusplus_mixing.exe でブレークポイントをトリガーしました。これは、ヒープの破損が原因である可能性があります。これは、c_cplusplus_mixing.exe または読み込まれた DLL のバグを示しています。これは、ユーザーが F12 キーを押したことが原因である可能性もあります。 c_cplusplus_mixing.exe にフォーカスがあります。出力ウィンドウにさらに診断情報が表示される場合があります。」

コール スタックはあまり意味がないようです (少なくとも私のような初心者にとっては)。
コール スタック:

ntdll.dll!775c542c()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
ntdll.dll!7758fdd0()
ntdll.dll!7755b3fc()

注意してください、私はビジュアル スタジオ 2008 を使用し、デバッグ ビルドを実行しています。(リリースも機能しません)。
誰かが私が間違っている場所を教えてください! 詳細が必要な場合はお知らせください。


ハサン、よろしくお願いします。

4

2 に答える 2

3

問題は、ExpandArrayOfInts が、再割り当てする必要があるポインターへのポインターではなく、int へのポインターを受け取っていることです。次のようになります。

int ExpandArrayOfInts(int** arrayToExpand, int expandBy, int inArraySize, int* outArraySize)

次に、次のように呼び出します。

ExpandArrayOfInts(&arrayDnmc, 5, arraySize, &arraySize))

スタックオーバーフローでポインターに関連する質問を探して、それらをよりよく理解することをお勧めします。

于 2011-03-20T08:56:23.583 に答える
1

realloc()私のシステムのドキュメントから:

realloc() は、新しく割り当てられたメモリへのポインタを返します。これは、あらゆる種類の変数に対して適切に配置され、 ptr とは異なる場合があり、リクエストが失敗した場合は NULL になります。

あなたのExpandArrayOfInts()宣言と実装では、 realloc が実際のポインターを変更することを許可していませんmain()。その値は変更できないと暗黙的に想定しています。realloc()メモリ領域を移動し別のポインターを返す場合、呼び出されたポインターで呼び出しますfree()。ただし、プログラムの残りの部分は、現在は無効になっている元の値を使用して続行するため、クラッシュします。

代わりに、ポインターからポインターへのポインターを使用して、参照によってメモリ領域ポインターを渡す必要があります。

int ExpandArrayOfInts(int** arrayToExpand, int expandBy, int inArraySize, int* outArraySize)
.
.
.
*arrayToExpand = (int*)realloc(*arrayToExpand, newSize * sizeof(int));
于 2011-03-20T09:02:26.397 に答える