如何在函数内返回其值后删除指针

时间:2010-06-30 00:54:31

标签: c++ pointers memory-management

我有这个功能:

char* ReadBlock(fstream& stream, int size)
{
    char* memblock;
    memblock = new char[size];
    stream.read(memblock, size);
    return(memblock);
}

每次必须从文件中读取字节时,都会调用该函数。我认为每次使用它都会分配新的内存,但是一旦我处理了数组内的数据,我怎么能释放内存呢?我可以从功能外部做到吗?通过分配大块处理数据比分配和删除小块数据提供更好的性能?

非常感谢你的帮助!

7 个答案:

答案 0 :(得分:15)

使用delete[]释放动态数组:

char* block = ReadBlock(...);
// ... do stuff
delete[] block;

但理想情况下,您不在此处使用手动内存管理:

std::vector<char> ReadBlock(std::fstream& stream, int size) {
    std::vector<char> memblock(size);
    stream.read(&memblock[0], size);
    return memblock;
}

答案 1 :(得分:5)

完成后,只需delete[]此函数的返回值。你从外面删除它并不重要。只是在完成使用之前不要删除它。

答案 2 :(得分:4)

可以致电:

char * block = ReadBlock(stream, size);
delete [] block;

但是...这是很多堆分配没有收获。考虑采用这种方法

char *block = new char[size];
while (...) {
  stream.read(block, size);
}
delete [] block;

*注意,如果size可以是编译时常量,则可以叠加分配block

答案 3 :(得分:1)

是。您可以从函数外部调用delete。在这种情况下,我可以建议使用std :: string,这样你就不必担心管理了吗?

答案 4 :(得分:1)

首先要注意的是:使用new和delete分配的内存是完全全局的。当指针超出范围或退出函数时,事物不会自动删除。只要你有一个指向分配的指针(例如指针在那里返回),你就可以随时随地删除它。诀窍,就是确保其他东西不会在你知道的情况下删除它。

这是fstream读取功能具有的功能结构的好处。很明显,所有的功能都是将'size'字节数读入你提供的缓冲区,无论是使用new分配缓冲区,无论是静态缓冲区还是全局缓冲区,甚至是本地缓冲区,甚至只是指向本地结构的指针。并且相当清楚的是,该函数在读取数据后,将对您传递的缓冲区不再执行任何操作。

另一方面,采用ReadBlock函数的结构;如果你没有代码,那么确切地知道它返回的内容会很棘手。它是否返回指向新内存的指针?如果是这样,它希望你删除它?它会删除它自己吗?如果是的话,何时?它甚至是一个新的指针?它只是将地址返回给某个共享静态缓冲区?如果是这样,缓冲区何时变为无效(例如,被其他东西覆盖)

查看ReadBlock的代码,显然它正在返回一个指向new'd内存的指针,并希望你在完成它时删除它。在删除之前,该缓冲区永远不会被覆盖或变为无效。

速度方面,这就是fsream.read的另一个好处,那就是“你整理缓冲区”的方法:你可以选择何时分配内存。如果您要“读取数据,处理,删除缓冲区,读取数据进程删除缓冲区等等......”只需分配一个缓冲区就会更有效率(达到您需要的最大大小,这将是正如斯蒂芬所建议的那样,你最大的单一阅读的大小)只是用于所有事情。

答案 5 :(得分:0)

如何使用静态char * memblock;它只会被初始化一次,并且不会每次都为memblock分配一个新的空间。

答案 6 :(得分:0)

我有一个类似的问题,并制作了一个简单的程序来演示为什么在函数外调用delete []仍会取消分配在函数内分配的内存:

#include <iostream>
#include <vector>

using namespace std;

int *allocatememory()

{
    int *temppointer = new int[4]{0, 1, 2, 3};
    cout << "The location of the pointer temppointer is " << &temppointer << ". Locations pointed to by temppointer:\n";
    for (int x = 0; x < 4; x++)
        cout << &temppointer[x] << " holds the value " << temppointer[x] << ".\n";
    return temppointer;
}

int main()
{
    int *mainpointer = allocatememory();
    cout << "The location of the pointer mainpointer is " << &mainpointer << ". Locations pointed to by mainpointer:\n";
    for (int x = 0; x < 4; x++)
        cout << &mainpointer[x] << " holds the value " << mainpointer[x] << ".\n";

    delete[] mainpointer;
}

这是在我的终端上从该程序读取的结果:

指针临时指针的位置为0x61fdd0。临时指针指向的位置:

0xfb1f20的值为0。

0xfb1f24保留值1。

0xfb1f28保留值2。

0xfb1f2c保留值3。

指针主指针的位置是0x61fe10。主指针指向的位置:

0xfb1f20的值为0。

0xfb1f24保留值1。

0xfb1f28保留值2。

0xfb1f2c保留值3。

此读数表明,尽管temppointer(在allocatememory函数中创建)和mainpointer具有不同的值,但它们指向同一位置的内存。这说明了为什么对mainpointer调用delete []还会取消分配temppointer指向的内存,因为该内存位于同一位置。