C++ 中的 new 关键字和无匹配的操作符错误

本文将讨论在 C++ 中使用 new 关键字。新手程序员在使用 new 关键字时通常会犯很多错误。

我们还将讨论他们犯的一些最常见的错误及其潜在的修复方法。

C++ 中的 new 关键字

new 关键字用作向操作系统发出请求以在堆内存上分配一些空间的运算符。如果堆上可用的所需内存量,则分配它,并在指针变量中返回已分配和初始化内存的地址。

使用 new 关键字的语法是:

datatype pointer_variable_name = new datatype;

此数据类型也可以是一些隐式数据类型或任何类名。当我们使用 new 关键字创建类的指针变量时,将调用类构造函数,并在堆上分配内存。

如果我们不使用 new 关键字并且变量在堆栈上初始化,则该变量在超出范围时会自动销毁。但堆变量并非如此。

堆变量不会自动销毁;相反,它们需要使用 delete 运算符手动销毁;否则,它们会在内存中悬空,从而导致内存泄漏问题。

让我们看看下面的例子。

#include <iostream>using namespace std;
int main () {
   int *intPtr = new int;
   *intPtr = 10;
   cout << "Value of Integer pointer is: " << *intPtr << endl;
   delete intPtr;
   return 0;
}

输出:

Value of Integer pointer is: 10

C++ 中 new 关键字的常见错误

在某些情况下,程序员没有用正确的数据初始化它而使用未分配的数据,导致一些未知或不需要的数据会干扰程序执行。例如,有两种情况:

int *ptr = new int;   //situation 1
int *ptr2 = new int[5]; //situation 2

在第一种情况下,内存分配给单个变量,而在第二种情况下,内存分配给 5 个整数变量,即在堆上创建一个包含 5 个索引的数组。

假设我们通过使用第一种情况声明指针来访问 ptr[3]。在这种情况下,我们正在访问一个未分配的空间,这可能会导致一些未知的错误,因为我们不知道之前在该内存位置放置了什么。

因此,在分配和使用堆上分配的内存时,我们必须非常小心。

考虑一种情况,我们有一个类的指针,我们需要创建一个类对象数组。

class Students
{
    int roll_num;
    string name;
};
int main()
{
    Students *student_list = new Students[10];
    for (int k = 0; k < 10; k++)
    {
        student_list[k] = new Students(); //line 10
    }
}

在上面的代码片段中,在第 10 行,我们在数组的每个索引处初始化对象。但是这一行会产生这样的错误:

/tmp/qqnmmMnApj.cpp: In function 'int main()':
/tmp/qqnmmMnApj.cpp:14:40: error: no match for 'operator=' (operand types are 'Students' and 'Students*')
   14 |         student_list[k] = new Students();
      |                                        ^

这是因为数组 student_list 的每个索引都是 Students 类的对象,而不是 Students 类的指针。因此,我们不需要一个 new 关键字来初始化它。

它应该像这样初始化:

student_list[k] = Students();

另一个常见错误是访问已删除或释放的内存位置。在某些情况下,某些函数使用 delete 运算符从堆中释放分配的内存,并且在程序中的任何其他点,你尝试访问该位置。

这可能会导致错误并且很难追踪,尤其是在处理大型项目时。考虑下面的例子。

int main()
{
   int *p = new int;
   *p = 5;
   cout<<"before deletion: "<<*p<<endl;
   delete p;
   cout<<"After deletion: "<<*p<<endl;
}

输出:

before deletion: 5
After deletion: 0

我们可以在输出中看到,删除后,该值从内存中被擦除;因此,它返回零。在较大的项目中,这可能会在运行时导致不需要的错误,因为在某些情况下,释放的内存位置可能被其他程序获取,并且包含可能干扰程序逻辑的其他数据。