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

问题描述 投票:32回答:7

我具有此功能:

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

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

非常感谢您的帮助!

c++ pointers memory-management
7个回答
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;
}

5
投票

delete[]完成此函数后的返回值。从外部删除它都没关系。请不要在完成使用前删除它。


4
投票

可以致电:

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

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

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

**,如果size可以是编译时间常数,则可以仅堆栈分配block


1
投票

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


1
投票

首先要注意:分配给new和delete的内存是完全全局的。当指针超出范围或退出函数时,不会自动删除所有内容。只要您有一个指向分配的指针(例如在该指针处返回的指针),就可以随时随地删除它。诀窍在于确保您不会在不知情的情况下删除其他内容。

这对fstream读取函数具有的函数结构有好处。很明显,该函数要做的就是将“大小”字节数读入您提供的缓冲区中,无论该缓冲区是否已使用new分配,是静态缓冲区还是全局缓冲区,甚至本地缓冲区,甚至只是指向本地结构的指针。而且也很清楚,一旦读取了数据,该函数就不会对您传递的缓冲区做任何其他处理。

另一方面,采用ReadBlock函数的结构;如果您没有相应的代码,则很难弄清楚它到底要返回什么。它是否返回指向新内存的指针?如果是这样,它是否希望您将其删除?它会删除它的自我吗?如果是这样,什么时候?它甚至是新的指针吗?它只是将地址返回到某些共享的静态缓冲区吗?如果是这样,什么时候缓冲区会失效(例如,被其他东西覆盖)

查看ReadBlock的代码,很明显,它正在返回指向新内存的指针,并且期望您在完成处理后将其删除。该缓冲区将永远不会被覆盖或变为无效,直到您将其删除。

速度方面,这是fsream.read的“您整理缓冲区”方法的另一个优点:您可以选择何时分配内存。如果您要“读取数据,处理,删除缓冲区,读取数据过程,删除缓冲区等...”,则仅分配一个缓冲区(达到所需的最大大小)将会更加高效。您最大的单次阅读的大小),然后将其用于所有内容,如Stephen所建议。


0
投票

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


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.