0

所以我的代码假设将数字插入动态数组,如果需要更多容量,则向数组添加更多容量,从数组中删除数字,然后确保唯一的 NULLS 出现在数组的末尾。它还告诉用户数组中有多少个数字以及数组的总大小是多少。我的问题是当我从数组中删除一个数字时,它有时会打印出我的数组中有一个数字 -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 ::list及其方法。如果您需要数据位于动态数组中,则使用std::vector擦除删除习惯用法进行删除。insertremove

我必须指出,由于您的问题是“删除动态数组中的 int 值并将其设置为 NULL ”,因此将 int 设置NULL为本质上是将其设置为 value 0,因为NULL往往是对0. 因此,如果您的列表包含零,则此设置NULL和检查是否相等NULL将完全破坏您的算法逻辑。C++11 有nullptr一个不能分配给 int 的实际 null 类型来处理这类问题。

于 2012-08-04T18:11:06.883 回答
1

具体问题是您没有tempArray在函数中初始化新数组(resp。)Resize

打电话时

int* tempArray = new int[newCapacity];

数组可以包含任意值。仅从newCapacity-1旧数组中复制值,因此最后一个值未定义。它可能是 0,但不一定是。利用

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

用零初始化你的数组。

除此之外,还有一些其他问题:

  • 在分配新数组之前不要删除旧数组。为此使用delete[] gArray。也不tempArray删!
  • 您不需要复制值两次。只是到一个gArray = tempArray(删除旧的后gArray,见上文)
  • 您假设它newCapacity比(您从旧数组gCapacity复制值)大一。newCapacity-1最好是复制gCapacity值。
  • 只增长一的动态数组效率低下,因为添加一个值需要线性时间(插入一个值时必须复制所有旧值)。通常,每次空间不足时,数组的大小都会增加一倍,这平均会产生恒定的插入时间。
  • NULL 通常只用于指针。对于整数,它等于零,这意味着您不能存储0在数组中(根据您的要求)
  • 在生产代码中,我 强烈建议使用std::vector而不是任何本地解决方案。

编辑

请参阅@StackUnderflows 答案以了解可能是错误的真正原因。如果你在 Debug 模式下运行,一些编译器会自动为你初始化数组,这可能是这里的 ccase。

另一方面,gArray[i]=gArray[i+1]您的函数中的行肯定是错误的,因为它访问的值超出了数组的限制。Remove

于 2012-08-04T18:05:25.803 回答
1

问题发生在Removewhen you do的第二个循环的最后一次迭代中gArray[i] = gArray[i + 1]。在最后一次迭代中,gArray[i + 1]实际上是数组末尾的一个,因此您现在处于未定义的行为领域。您正在将此未定义的值分配给最后一个元素gArray[i]


我建议std::vector<int>改用。它在引擎盖下操纵一个数组,当您添加更多元素时,该数组会为您增长/调整大小。

于 2012-08-04T18:07:18.353 回答