简体   繁体   English

如何通过引用或指针传递的指针正确释放main中的内存?

[英]how to properly free memory in main that is allocated in a function through pointer passed by reference or by pointer?

I'm writing a function to be called by main which allocate memory to a few pointers declared in main. 我正在编写一个由main调用的函数,它将内存分配给main中声明的几个指针。 I learnt I can do this by using pointer to pointer or reference to pointer, but I'm having problem deallocating these memories in main. 我知道我可以通过使用指针指针或引用指针来做到这一点,但我有问题在main中释放这些内存。 please help me with what is wrong in the following code: 请帮我解决以下代码中的错误:

1. using pointer to pointer: 1.使用指针指针:

void fun1(int **a, double **b, char **c)
{

    *a=new int[20];
    *b=new double[20];
    *c=new char[10];

    for (int i=0;i<20;i++){
        (*a)[i]=i;
        (*b)[i]=sqrt((double)((*a)[i]));
    }
    *c="0123456789";

}


int _tmain(int argc, _TCHAR* argv[])
{
    int *a;
    double *b;
    char *c;

    fun1(&a,&b,&c);
    cout<<"a & b are:"<<endl;
    for(int i=0;i<20;i++)
        cout<<a[i]<<"\t"<<b[i]<<endl;
    cout<<"c is: "<<c<<endl;

    delete[] a;
    delete[] b;
    delete[] c;
    return 0;
}

2. using reference to pointer: 2.使用对指针的引用:

void fun1(int*& a, double*& b, char*& c)
{

    a=new int[20];
    b=new double[20];
    c=new char[10];

    for (int i=0;i<20;i++){
        a[i]=i;
        b[i]=sqrt((double)a[i]);
    }
    c="0123456789";

}


int _tmain(int argc, _TCHAR* argv[])
{
    int *a;
    double *b;
    char *c;

    fun1(a,b,c);
    cout<<"a & b are:"<<endl;
    for(int i=0;i<20;i++)
        cout<<a[i]<<"\t"<<b[i]<<endl;
    cout<<"c is: "<<c<<endl;

    delete[] a;
    delete[] b;
    delete[] c;
    return 0;
}

thanks a lot! 非常感谢!

This in fun1() 这在fun1()

*c="0123456789";

followed by this in main() main()后跟这个

delete[] c;

is undefined behavior since you try to delete[] a string literal. 是因为您尝试delete[]字符串文字而未定义的行为。

The problem has nothing to do with how you are passing the pointers, and everything to do with how you are initializing the contents of c. 这个问题与你如何传递指针无关,而与你如何初始化c的内容有关。 c ends up pointing to memory that was not created by new[] and so cannot be freed by delete[]. c最终指向不是由new []创建的内存,因此无法通过delete []释放。

int *a;
double *b;
char *c;

fun1(a,b,c);

You meant: 你的意思是:

int* a;
double* b;
char* c;

fun1(&a,&b,&c);

And then you're ok. 然后你没事。

However, as sharptooth says, your delete[] c is broken because you just reassigned the pointer to a string literal instead of copying the chars. 但是,正如sharptooth所说,你的delete[] c被破坏了,因为你只是将指针重新分配给字符串文字而不是复制字符。


Please, use std::vector and std::string instead of all this nonsense: 请使用std::vectorstd::string代替所有这些废话:

#include <iostream>
#include <string>
#include <vector>

void fun1(std::vector<int>& a, std::vector<double>& b, std::string& c)
{
    a.resize(20);
    b.resize(20);

    for (int i = 0; i < 20; i++) {
        a[i] = i;
        b[i] = sqrt((double)a[i]);
    }

    c = "0123456789";
}


int main(int argc, char* argv[])
{
    std::vector<int> a;
    std::vector<double> b;
    std::string c;

    fun1(a,b,c);

    std::cout << "a & b are: \n";
    for (int i = 0; i < 20; i++)
        std::cout << a[i] << "\t" << b[i] << " \n";

    std::cout << "c is: " << c << std::endl;
}

There is no "proper" way to do that, your program design is flawed. 没有“正确”的方法,你的程序设计是有缺陷的。 The very same code module that is allocating the dynamic memory shall be the same one that frees it. 分配动态内存的相同代码模块应该是释放它的相同模块。 So if fun1() is located in fun.c, there should also be another function in fun.c called cleanup() or whatever, which cleans up the mess fun1() made. 因此,如果fun1()位于fun.c中,那么fun.c中还应该有另一个函数叫做cleanup()或者其他什么,这样可以清理fun fun()。 Otherwise your programs are soon turning into happy-memory-leak-land. 否则你的程序很快就会变成幸福记忆泄漏的土地。

A better design in this case is to let main() allocate the memory, then pass the allocated buffers as parameter to the function. 在这种情况下更好的设计是让main()分配内存,然后将分配的缓冲区作为参数传递给函数。

This concept is known as "private encapsulation" in object-oriented programming. 这种概念在面向对象编程中称为“私有封装”。

What you are doing is a ticket for disaster. 你正在做的是灾难的门票。 I strongly recommend using stl containers. 我强烈建议使用stl容器。 It is usually recommended to use containers that handle deallocation for you, because deallocation is a frequent cause of annoying bugs. 通常建议使用处理释放的容器,因为解除分配是导致烦扰的常见错误的常见原因。 Try to avoid raw pointers, they are very rarely an advantage and make your life more complicated. 尽量避免原始指针,它们很少是优势,让你的生活变得更加复杂。

#include <vector>
#include <string>
#include <iostream>
using namespace std;

void fun1(vector<int>& a, vector<double>& b, string& c)
{
    size_t size = 20;
    a.resize(size);
    b.resize(size);
    for (int i=0;i<size;i++){
        a.at(i) = i;
        b.at(i) = sqrt(i); // auto conversion to double
    }
    c="0123456789";
}

int _tmain(int argc, _TCHAR* argv[])
{
    vector<int> a;
    vector<double> b;
    string c;

    fun1(a,b,c);
    cout<<"a & b are:"<<endl;
    for(int i=0;i<a.size();i++)
        cout<<a.at(i)<<"\t"<<b.at(i)<<endl;
    cout<<"c is: "<<c<<endl;

    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM