【问题标题】:C++ memory deallocation, is it needed in this case?C ++内存释放,在这种情况下是否需要?
【发布时间】:2023-03-29 12:18:01
【问题描述】:

我正在尝试制作账单及其编号(标识符)。它们的编号是自动生成的,长度为 9 个字符。

这是我的代码1

#include <iostream>
using namespace std;

int counter = 1234;
char * BillNumber()
{
    if (counter == 1)
    {
        counter++;
        return "000000001";
    }

    int n = 0, c = counter;

    while (c != 0)
    {
        n++;
        c /= 10;
    }

    char * nrBill = new char[n + 1];
    _itoa_s(counter, nrBill, n + 1, 10);
    nrBill[n + 1] = '\0';

    int difference = 9 - n;
    if (difference == 0)
        return nrBill;

    char * helper = new char[difference + 1];
    for (int i = 0; i < difference + 1; i++)
    {
        helper[i] = '0';
        if (i == difference)
            helper[i] = '\0';
    }

    strcat_s(helper, 10, nrBill);
    counter++;
    return helper;
}

int main()
{
    char * bill[10];

    for (int i = 0; i < 10; i++)
    {
        bill[i] = BillNumber();
    }

    for (int i = 0; i < 10; i++)
    {
        cout << bill[i] << endl;
    }

    //Deallocation
    /*for (int i = 0; i < 10; i++)
    {
        delete[] bill[i];
    }*/
    return 0;
}

当我尝试像评论中那样释放内存时,我得到一个错误。我明白我为什么得到它,我的意思是我什至没有在main 函数中分配我的内存。所以我实际上需要在函数BillNumber 中释放它。但我认为函数中也不需要。

所以我的问题是:

这里真的需要内存释放吗?

1:我知道我没有使用 c++ 编码标准,所以请不要抱怨。*

【问题讨论】:

  • 您的代码充满了错误。这不是一个调试服务,尽管看起来。
  • 为什么你认为不需要内存释放?任何时候使用new 分配内存时,都必须使用delete 解除分配。规则很简单。您可以使用 RAII 和标准 C++ 习惯用法使其更简单,但您似乎有理由避免使用这些。
  • @CodyGray 好吧,我现在知道我需要在我的函数 BillNumber() 中取消分配 nrBill ,但是我该如何取消分配 helper ?我的意思是我不能这样做:delete[] helper; return helper;
  • @Kapobajza 您将指针返回到助手并将其存储在账单中,因此您只需在账单中释放它。
  • 对,你不能那样做。这就是为什么 C++ 程序员使用对象来封装数据,这样他们就不必手动进行内存管理了。如果您想以 C 方式执行此操作,则从 BillNumber() 返回一个指针,它将 helper 的所有权从被调用函数 (BillNumber) 转移到调用函数 (main)。调用函数main 现在对delete[] helper 使用完毕后负责。

标签: c++ pointers memory-management


【解决方案1】:

我的意思是我什至没有在主函数中分配我的内存。所以我实际上需要在函数 BillNumber 中释放它。但我认为函数中也不需要。

分配发生在哪里并不重要,关键是如果你分配了一些东西,你需要释放它。对于您的代码,由于您仍在使用在 main() 中调用的 BillNumber() 之后的指针,因此您必须稍后在 main() 中释放它们。

当我尝试像注释中那样释放内存时,出现错误。

您需要调试程序才能找出真正的问题,这是一种可能性:

char * nrBill = new char[n + 1];
_itoa_s(counter, nrBill, n + 1, 10);
nrBill[n + 1] = '\0';

nrBill[n + 1] 正在超出数组的范围。

【讨论】:

    【解决方案2】:

    因为您正在执行此char * nrBill = new char[n + 1]; 和此char * helper = new char[difference + 1];,您实际上是在堆上分配内存,除非您明确调用它,否则不会释放。你应该打电话:

    delete []nrBill; 
    delete []helper[]; 
    

    在从函数返回之前,否则会出现内存泄漏。对象 nrBill 和 helper 永远不会被释放,直到程序结束,这在您的情况下不是问题,因为它很快就会结束,并且内存会恢复,但是如果您开发的应用程序会产生内存泄漏并且长时间工作,那么这将是一个真正的问题。

    【讨论】:

    • 我知道我需要delete[] nrBill,但是如果我这样做delete[] helper,那我将如何返回它?我不能返回一个空字符指针。
    • delete[]helper 应该在你的主函数中调用,对不起!还有你给它的名字,比如 delete[] bill。
    【解决方案3】:

    首先,当您返回helper 时,不要释放nrBill。那是内存泄漏和问题。

    至于您的问题,需要释放内存,因为您手动分配了内存。但是,在您的情况下,不会有任何内存泄漏(除了我上面提到的那个),因为程序完成(主要返回)并且所有分配的内存都被释放了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-10
      • 2017-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多