0

したがって、私のコードは、動的配列に数値を挿入し、必要に応じて配列に容量を追加し、配列から数値を削除して、配列の最後にNULLのみが発生することを確認することを想定しています。また、配列に含まれる数値の数と、配列の合計サイズをユーザーに通知します。私の問題は、配列から番号を削除すると、配列に番号-33686019があると出力されることがあります。これはあまり発生しませんが、まったく発生したくありません。

#include <stdio.h>
#include <iostream>

int* gArray = NULL;
int gSize = 0;
int gCapacity = 0;
void Insert(int value);
void Remove(int value);
void Resize(int newCapacity);
void Print(void);


void main()
{
int input = 0;

while(input != 3)
{
    printf(">=== Dynamic Array ===\n");
    printf("What do you want to do?\n");
    printf("1. Insert\n");
    printf("2. Remove\n");
    printf("3. Quit\n");
    printf("Your choice: ");
    scanf_s("%d", &input);
    printf("\n\n");

    int value = 0;

    switch(input)
    {
    case 1:
        {
            printf("Enter a number: ");
            scanf_s("%d", &value);
            Insert(value);
            Print();
            break;
        }
    case 2:
        {
            printf("Enter number you wish to delete: ");
            scanf_s("%d", &value);
            Remove(value);
            Print();
            break;
        }
    case 3:
        {
            break;
        }
    default:
        {
            printf("Invalid selection\n");
        }
    }
}
}
void Insert(int value)
{
bool valueSet = false;

while(valueSet == false)
{
    if(gArray == NULL)
    {
        Resize(1);
        gArray[gSize] = value;
        ++gSize;
        valueSet = true;
    }
    else if(gArray[gCapacity] == NULL)
    {
        gArray[gSize] = value;
        ++gSize;
        valueSet = true;
    }
    else if(gArray[gCapacity] != NULL)
    {
        Resize((gCapacity + 1));
        gArray[gSize] = value;
        ++gSize;
        valueSet = true;
    }
}

}
void Resize(int newCapacity)
{
int* tempArray = new int[newCapacity];
std::copy(gArray, gArray+(newCapacity-1), tempArray);
gArray = new int[newCapacity];
std::copy (tempArray, tempArray+(newCapacity-1), gArray);
gCapacity = newCapacity;
}
void Remove(int value)
{
for(int i = 0; i < gCapacity; ++i)
{
    if(gArray[i] == value)
    {
        gArray[i] = NULL;
        --gSize;
    }
}
for(int i = 0; i < gCapacity; ++i)
{
    if(gArray[i] == NULL)
    {
        gArray[i] = gArray[(i + 1)];
        gArray[(i + 1)] = NULL;
    }
}
}
void Print(void)
{
printf("Array contains: ");
for(int i = 0; i < gCapacity; ++i)
{
    if(gArray[i] != NULL)
    {
        printf("%d, ", gArray[i]);
    }
}
printf("size = %d, capacity = %d\n", gSize, gCapacity);


}
4

3 に答える 3

2

オプションとして、c ++標準ライブラリを使用しているので、すべてのコードを削除し、std::listinsertとそのremoveメソッドを使用します。データを動的配列にする必要がある場合は、std::vectorとeraseremoveイディオムを使用して削除します

あなたの質問は「動的配列のint値を削除してNULLに設定する」であるため、intを設定するNULLと、本質的に値0に設定されることになります。NULLこれは、の定義になる傾向があるためです0。したがって、リストにゼロが含まれている場合、この設定NULLと等しいかどうかのチェックNULLは、アルゴリズムのロジックを完全に破壊します。C ++ 11にはnullptr、この種の問題に対処するために、intに割り当てることができない実際のnull型があります。

于 2012-08-04T18:11:06.883 に答える
1

tempArray具体的な問題は、関数で新しい配列(または)を初期化しないことですResize

電話するとき

int* tempArray = new int[newCapacity];

配列には任意の値を含めることができます。古い配列から値のみnewCapacity-1がコピーされるため、最後の値は未定義です。0かもしれませんが、そうではありません。使用する

std::fill(tempArray, tempArray+newCapacity, 0);

配列をゼロで初期化します。

それとは別に、他にもいくつか問題があります。

  • 新しいアレイを割り当てる前に、古いアレイを削除しないでください。そのために使用delete[] gArrayします。またtempArray、削除されません!
  • 値を2回コピーする必要はありません。ちょうどgArray = tempArray(古いものを削除した後gArray、上記を参照)
  • これは(古い配列から値をコピーする)newCapacityよりも1だけ大きいと想定します。代わりに値をコピーすることをお勧めします。gCapacitynewCapacity-1gCapacity
  • 値を追加するには線形時間がかかるため、1つだけ大きくなる動的配列は非効率的です(単一の値を挿入する場合は、古い値をすべてコピーする必要があります)。通常、スペースが不足するたびに配列のサイズを2倍にします。これにより、平均して一定の挿入時間が得られます。
  • NULLは通常、ポインタにのみ使用されます。intsの場合、ゼロに等しいため0、配列に格納できません(要件が与えられた場合)
  • 本番コードでは、 自家製のソリューションの代わりに使用することを強くお勧めします。std::vector

編集

おそらくエラーの本当の原因については、@StackUnderflowsの回答を参照してください。デバッグモードで実行する場合、一部のコンパイラは自動的に配列を初期化します。これは、ここではccaseである可能性があります。

一方、関数のgArray[i]=gArray[i+1]行はRemove、配列の制限を超える値にアクセスするため、間違いなく間違っています。

于 2012-08-04T18:05:25.803 に答える
1

この問題は、実行するときの2番目のループの最後の反復で発生しRemoveますgArray[i] = gArray[i + 1]。最後の反復でgArray[i + 1]は、実際には配列の終わりを1つ過ぎているため、未定義の動作領域にいます。この未定義の値を最後の要素に割り当てていますgArray[i]


代わりに使用することをお勧めしstd::vector<int>ます。それはあなたがより多くの要素を追加するにつれてあなたのために成長/サイズ変更する内部の配列を操作します。

于 2012-08-04T18:07:18.353 に答える