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

时间:2011-03-10 15:12:05

标签: c++ memory-management pass-by-reference

我正在编写一个由main调用的函数,它将内存分配给main中声明的几个指针。我知道我可以通过使用指针指针或引用指针来做到这一点,但我有问题在main中释放这些内存。请帮我解决以下代码中的错误:

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。使用对指针的引用:

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;
}

非常感谢!

5 个答案:

答案 0 :(得分:8)

这在fun1()

*c="0123456789";

后面是main()

delete[] c;

是未定义的行为,因为您尝试delete[]字符串文字。

答案 1 :(得分:2)

这个问题与你如何传递指针无关,而与你如何初始化c的内容有关。 c最终指向不是由new []创建的内存,因此无法通过delete []释放。

答案 2 :(得分:1)

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

fun1(a,b,c);

你的意思是:

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

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

然后你没事。

但是,正如锐齿所说,你的delete[] c被破坏了,因为你只是将指针重新分配给字符串文字而不是复制字符。


请使用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;
}

答案 3 :(得分:0)

没有“正确”的方法,你的程序设计是有缺陷的。分配动态内存的相同代码模块应该是释放它的相同模块。因此,如果fun1()位于fun.c中,那么fun.c中还应该有另一个函数叫做cleanup()或者其他什么,这样可以清理fun fun()。否则你的程序很快就会变成幸福记忆泄漏的土地。

在这种情况下更好的设计是让main()分配内存,然后将分配的缓冲区作为参数传递给函数。

这个概念在面向对象编程中被称为“私有封装”。

答案 4 :(得分:0)

你正在做的是灾难的门票。我强烈建议使用stl容器。通常建议使用处理释放的容器,因为解除分配是导致烦扰的常见错误的常见原因。尽量避免原始指针,它们很少有优势,让你的生活变得更加复杂。

#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;
}