删除操作符的未定义行为



我对c++比较陌生,我正在学习指针。我试图动态地为一个数组分配一些内存,发现了这个问题。

这是我的代码,

#include <iostream>
int main(){
int n = 5;
int *arr = new int(n*(sizeof(int)));
for(int i=0; i<n; i++)
*(arr+i) = i+1;
delete[] arr;
for(int i=0; i<n; i++)
std::cout << *(arr+i) << " ";
}

和预期的输出是一些垃圾值,因为我使用delete操作符释放内存,然而,这是我的输出:

首次运行:755597344 47626 2043 4 5

第二运行:-1437908960 62859 2043 4 5

第三运行:-902037472 965 2043 4 5

我已经尝试了几次运行,但只有前3个值改变,而其他的似乎是数组仍然在那里,这可能是什么解释?

在这一小段代码中有多个错误和问题:

  • 表达式new int(n*(sizeof(int)))分配一个单个int值并初始化为值n*(sizeof(int))

    如果您想为int值的数组分配空间,则需要使用new[],如new int[n]

  • 由于上述问题,您将使超出分配内存的范围,导致未定义行为

  • 一旦您解决了问题1,您需要将new[]delete[]操作符配对。操作符不匹配还会导致未定义行为

  • 最后,一旦你删除了内存,你就不能再访问它,任何对指针解引用的尝试都会再次导致未定义的行为

总的来说,程序应该看起来像这样:

#include <iostream>
#include <cstdlib>
int main()
{
constexpr std::size_t n = 5;
// Allocate memory
int* arr = new[n];
// Initialize the memory
for (std::size_t i = 0; i < n; ++i)
{
arr[i] = i + 1;
}
// Display the memory
for (std::size_t i = 0; i < n; ++i)
{
std::cout << "arr[" << i << "] = " << arr[i] << 'n';
}
// Free the memory
delete[] arr;
}

以上所述和所做的,有更好的方法来创建固定或动态大小的数组。

如果你有一个固定大小的数组,它的大小在编译时是已知的,并且它的大小在运行时永远不会改变,使用std::array代替:

// Create and initialize array
std::array<int, 5> arr = {{ 1, 2, 3, 4, 5 }};
// Display array
for (int value : arr)
{
std::cout << value << 'n';
}

如果在编译时不知道大小,或者需要在运行时更改大小,则使用std::vector:

// Create a vector with five "zero-initialized" elements
std::vector<int> arr(5);
new int(n*(sizeof(int)));

只分配单个int,并将值设置为n*(sizeof(int))

如果你想要整型数组,你必须像下面这样做。

int *arr = new int[n];

最新更新