函数在不删除动态数组的情况下工作。程序有效且没有错误

Posted

技术标签:

【中文标题】函数在不删除动态数组的情况下工作。程序有效且没有错误【英文标题】:Function works without deleting the dynamic array. Program works and has no errors 【发布时间】:2016-05-23 10:36:21 【问题描述】:

我是 C++ 的学生和初学者。目前在课堂上我们正在练习指针、动态数组和函数。我写了一个没有错误的程序,它做了它必须做的事情。我的问题是它可以在不删除动态数组的情况下工作。 我们被要求将 delete[] 放入函数中

#include <iostream>
using namespace std;

char* Function (char c[], int numbers[])
    int k=0;

    for ( int i=0; i< 4;i++)
        k+=numbers[i];
    

    k++;
    char *result = new char[k];
    char *counter=result;

    for ( int i=0; c[i]!='\0';i++)
    
        int index = numbers[i];

        for (int j=0; j< index; j++)
        
            *counter=c[i];
            counter=counter+1;
        
     

     *counter='\0';

     return result;

 

int main ()

    char c[]="abcd";
    int numbers []=1,2,3,4;
    char d[]="ghj";
    int numbersx []=2,1,1;

    cout << Function(c,numbers);
    cout << Function(d,numbersx);

    return 0;   
 

我不清楚在这种情况下 delete[] 的位置。 我搜索了this recommends that i put the delete inside main 其他答案没有回答我的确切问题。

【问题讨论】:

建议作为一个好的做法。在小数组的情况下,它没有任何区别;但是对于大型数组,您需要使用它来释放内存。 哦,好吧,我对删除的位置感到困惑 它通常放在最后,当你不再需要数组时。 是的,但是如果我把它放在return之后,它仍然会被删除吗?它必须放在函数中,而不是 main 中。 如果你把delete [] 放在main 里面,那么它会正常工作。如果您将delete[] 放在Function 中但在return 之前,那么在这种情况下,您将返回一个指向已删除内存的指针(return result;),然后在main 中您将访问已删除的内存,该内存将具有未定义的行为。因此,如果您想将delete [] 放在“函数”中,但又想访问main 中的result,则创建result 指向的内存副本并从Function 返回。在Function返回后写delete[]不会删除内存。 【参考方案1】:

我的问题是它可以在不删除动态数组的情况下工作。

它可能会起作用......但它也会泄漏内存。在没有无限内存的计算机上,内存泄漏是一件坏事。

我不清楚在这种情况下 delete[] 的位置。

它的位置必须保证指向的对象在被删除后永远不会使用使用这里意味着访问对象的内存,例如通过取消引用指向它的指针。

如果我把它放在return之后还会被删除吗?

如果你的意思是它在Function 但在返回之后,那当然不是。返回后函数中没有任何内容。

它必须放在函数中而不是main中。

如果您要在Function 中删除,那么您将返回一个指向已删除对象的指针,这将是非常糟糕的。我建议放弃这个愚蠢的要求。

从技术上讲,main 永远不会取消对指针的引用,因此即使您确实在 Function 中删除,程序在技术上仍然具有明确定义的行为,即使返回值将完全无用。

【讨论】:

@KarstenKoop 正确。【参考方案2】:

在函数中删除它是可以的。只是不要再次释放/删除它。也可以在main()删除。

如果你不删除它,你不会有明显的问题(编译器不会抱怨,程序也不会崩溃)。但是,您会遇到内存泄漏,这绝对不是您想要的。

【讨论】:

【参考方案3】:

如果不释放内存,最终会导致内存泄漏。对于像这样的简单应用程序,您不太可能发现问题。对于较大/运行时间较长的应用程序,您在应用程序退出之前分配了大量数据,您最终将耗尽内存并且程序将崩溃和/或您的操作系统在将数据分页到磁盘时将缓慢爬行.

要释放内存但仍然打印一些输出,您需要这样的东西:

#include <iostream>
using namespace std;

void Function (char c[], int numbers[])
    int k=0;

    for ( int i=0; i< 4;i++)
        k+=numbers[i];
    

    k++;
    char *result = new char[k];
    char *counter=result;

    for ( int i=0; c[i]!='\0';i++)
    
        int index = numbers[i];

        for (int j=0; j< index; j++)
        
            *counter=c[i];
            counter=counter+1;
        
    

    *counter='\0';

    cout << result;

    delete [] result;
 

int main ()

    char c[]="abcd";
    int numbers []=1,2,3,4;
    char d[]="ghj";
    int numbersx []=2,1,1;

    Function(c,numbers);
    Function(d,numbersx);

    return 0;   

这是您在函数中获取delete[] 的唯一方法,因为正如其他人所说,您仍然需要访问内存以在函数返回后报告结果。

另一种方法是在 main 方法中调用 delete [] 两次,如下所示:

#include <iostream>
using namespace std;

char* Function (char c[], int numbers[])
    int k=0;

    for ( int i=0; i< 4;i++)
        k+=numbers[i];
    

    k++;
    char *result = new char[k];
    char *counter=result;

    for ( int i=0; c[i]!='\0';i++)
    
        int index = numbers[i];

        for (int j=0; j< index; j++)
        
            *counter=c[i];
            counter=counter+1;
        
    

    *counter='\0';

    return result;


int main ()

    char c[]="abcd";
    int numbers []=1,2,3,4;
    char d[]="ghj";
    int numbersx []=2,1,1;

    char* result = Function(c,numbers);
    cout << result;
    delete[] result;

    result = Function(d,numbers);
    cout << result;
    delete[] result;

    return 0;   

【讨论】:

@Igna:看看这部分代码“要释放内存但仍然打印一些输出,你需要这样的东西”。您的老师可能已经预料到了这一点。

以上是关于函数在不删除动态数组的情况下工作。程序有效且没有错误的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的动态数组可以在不调整大小的情况下工作? [复制]

在不破坏严格别名的情况下有效地生成字节缓冲区

为什么glDrawElments()在不使用任何着色器的情况下工作?

有没有办法在不使用单独的应用程序域的情况下删除 .dll 文件?

在不知道对象索引的情况下从数组中删除对象?

有没有办法在不使用(MFC)动态对象创建的情况下在 CSplitterWnd 中创建视图?