我具有此功能:
char* ReadBlock(fstream& stream, int size)
{
char* memblock;
memblock = new char[size];
stream.read(memblock, size);
return(memblock);
}
每当我必须从文件中读取字节时,都会调用该函数。我认为它每次使用都会分配新的内存,但是一旦处理完数组中的数据,如何释放内存?我可以从功能外部执行此操作吗?通过分配大块来处理数据比分配和删除小块数据能提供更好的性能?
非常感谢您的帮助!
使用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;
}
仅delete[]
完成此函数后的返回值。从外部删除它都没关系。请不要在完成使用前删除它。
您可以致电:
char * block = ReadBlock(stream, size);
delete [] block;
但是...这是很多堆分配,但没有收益。考虑采用这种方法
char *block = new char[size];
while (...) {
stream.read(block, size);
}
delete [] block;
**,如果size
可以是编译时间常数,则可以仅堆栈分配block
。
是。您可以从函数外部调用delete。不过,在这种情况下,我是否建议使用std :: string,这样您就不必自己担心管理了吗?
首先要注意:分配给new和delete的内存是完全全局的。当指针超出范围或退出函数时,不会自动删除所有内容。只要您有一个指向分配的指针(例如在该指针处返回的指针),就可以随时随地删除它。诀窍在于确保您不会在不知情的情况下删除其他内容。
这对fstream读取函数具有的函数结构有好处。很明显,该函数要做的就是将“大小”字节数读入您提供的缓冲区中,无论该缓冲区是否已使用new分配,是静态缓冲区还是全局缓冲区,甚至本地缓冲区,甚至只是指向本地结构的指针。而且也很清楚,一旦读取了数据,该函数就不会对您传递的缓冲区做任何其他处理。
另一方面,采用ReadBlock函数的结构;如果您没有相应的代码,则很难弄清楚它到底要返回什么。它是否返回指向新内存的指针?如果是这样,它是否希望您将其删除?它会删除它的自我吗?如果是这样,什么时候?它甚至是新的指针吗?它只是将地址返回到某些共享的静态缓冲区吗?如果是这样,什么时候缓冲区会失效(例如,被其他东西覆盖)
查看ReadBlock的代码,很明显,它正在返回指向新内存的指针,并且期望您在完成处理后将其删除。该缓冲区将永远不会被覆盖或变为无效,直到您将其删除。
速度方面,这是fsream.read的“您整理缓冲区”方法的另一个优点:您可以选择何时分配内存。如果您要“读取数据,处理,删除缓冲区,读取数据过程,删除缓冲区等...”,则仅分配一个缓冲区(达到所需的最大大小)将会更加高效。您最大的单次阅读的大小),然后将其用于所有内容,如Stephen所建议。
如何使用静态char *内存块;它只会被初始化一次,并且不会每次都向memblock分配新的空间。
我有一个类似的问题,并制作了一个简单的程序来演示为什么在函数外调用delete []仍会取消分配在函数内分配的内存: