簡體   English   中英

刪除動態數組中的int值並將其設置為NULL

[英]Removing int value in dynamic array and setting it to NULL

因此,我的代碼假定將數字插入動態數組中,如果需要更多的空間,則增加數組的容量,從數組中刪除數字,然后確保唯一的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);


}

一種選擇,因為您使用的是c ++標准庫,所以將刪除所有代碼,並使用std :: list及其insertremove方法。 如果您需要將數據存儲在動態數組中,請使用std :: vector擦除刪除慣用語進行刪除。

我必須指出,由於您的問題是“ 在動態數組中刪除int值並將其設置為NULL ”,因此將int設置為NULL本質上會將其設置為0 ,因為NULL往往是0的定義。 因此,如果您的列表包含零,則將此設置設置為NULL並檢查與NULL相等性將完全破壞算法的邏輯。 C ++ 11具有nullptr ,這是無法分配給int的實際null類型,用於處理此類問題。

具體的問題是您沒有在Resize函數中初始化新數組( tempArray )。

打電話時

int* tempArray = new int[newCapacity];

數組可以包含任意值。 從舊數組僅復制newCapacity-1值,因此最后一個值是不確定的。 它可能是0,但不是。 采用

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

用零初始化數組。

除此之外,還有其他一些問題:

  • 您不會在分配新數組之前刪除舊數組。 delete[] gArray使用delete[] gArray tempArray也不會被刪除!
  • 您無需復制兩次值。 只是對gArray = tempArray (刪除舊的gArray ,請參見上文)
  • 您假設newCapacity僅比gCapacity大1(從舊數組中復制newCapacity-1值)。 最好復制gCapacity值。
  • 僅增加一個的動態數組效率不高,因為添加值需要線性時間(插入單個值時必須復制所有舊值)。 通常,每次空間用盡時,數組的大小都會加倍,這樣平均可以得到恆定的插入時間。
  • NULL通常僅用於指針。 對於整數,它等於零,這意味着您不能在數組中存儲0 (根據您的要求)
  • 在生產代碼中,我強烈建議您使用std::vector而不是任何本地解決方案。

編輯

請參閱@StackUnderflows答案以獲取可能是該錯誤的真正原因。 如果以Debug模式運行,則某些編譯器會自動為您初始化數組,此處可能是ccase。

另一方面, Remove函數中的gArray[i]=gArray[i+1]行肯定是錯誤的,因為它訪問的值超出了數組的限制。

當您執行gArray[i] = gArray[i + 1]時,該問題發生在Remove的第二個循環的最后一次迭代中。 在最后一次迭代中, gArray[i + 1]實際上比數組末尾gArray[i + 1]一個,因此您現在處於未定義的行為區域。 您正在將此未定義的值分配給最后一個元素gArray[i]


我建議改用std::vector<int> 它操縱一個在幕后的數組,當您添加更多元素時,該數組會為您增長/調整大小。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM