如何在C++中为缓冲区分配更多内存?

3

我有指针 str

char* str = new char[10];

我使用内存块str来存储数据。

如何为str指向的缓冲区分配更多字节,而不会丢失已存储在缓冲区中的旧数据?


4
你应该参加一些关于编程的课程。 - Alexey Malistov
1
考虑使用 std::vector,它可以免费提供这个功能。 - David Rodríguez - dribeas
8个回答

17

使用 std::string 替代。它可以做到你需要的,而不必担心分配、复制等问题。你仍然可以通过 c_str() 函数访问原始内存。

甚至 std::vector<char> 也会很适合你。


8

new[] 另一个缓冲区,将数据复制到该缓冲区(使用 memcpy()),然后 delete[] 旧缓冲区,将新缓冲区地址分配给最初持有旧缓冲区地址的指针。


3

你不能使用new构造函数。相反,你需要使用老旧的mallocreallocfree(不要混用malloc/realloc/free和new/delete)。


4
实际上,你可以使用 "new[]" 来创建一个新缓冲区,复制数据,然后删除旧缓冲区。虽然这不是一行代码,但这就是 "realloc()" 函数的工作原理。 - sharptooth
1
@sharptooth:并不完全准确。操作系统(至少是Linux)会尝试在原地实际增加内存。如果在分配的空间后有足够的连续空间,则该操作将不会产生复制成本。 - David Rodríguez - dribeas
@dribeas - David Rodríguez:是的,就实现而言是这样的,但是OP并没有坚持“不复制”,他只是要求数据保留。 - sharptooth
@David:realloc的行为让很多程序员陷入麻烦。在我的看法中,在调试编译中,realloc应该总是移动块,这样程序员就不会养成忽略其返回地址的习惯。 - Zan Lynx

1

如果你真的在使用C++,最正确的解决方案应该是使用std::vector。我假设你没有将那个信息作为标准字符串使用,在这种情况下,你应该使用std::string(它是std::vector的一个特化版本,所以没什么大不了的)。你正在创建至少10个字符。这让我想到你可能相当确定你需要10个字符,但也许你会需要更多。也许你担心分配和释放内存所涉及的性能问题。在这种情况下,你可以创建你的字符串,然后保留你预计需要的估计容量,这样至少在达到那个限制之前就不会有任何重新分配。

int main()
{
    std::string s;
    s.reserve( 10 );
    // do whatever with s
}

正如其他人已经指出的那样,使用std::string或std::Vector将使您受益于忘记复制、调整大小或删除保留的内存。


1

realloc 函数是你所寻找的。你必须使用 malloc/free 而不是 new/delete 才能使用它。


1
不确定为什么这个被踩了,原帖的作者要么需要使用std::string/std::vector<char>,要么需要使用malloc/realloc/free来分配内存,而不是使用new/delete。 - Narendra N

0

你需要分配一个不同且更大的字符串数组,并将数据从原始字符串复制到新的字符串数组中。


0

请注意,realloc 可能会静默地移动内存分配,从而使其他指针失效。 - Brian Rasmussen
你指出了正确的问题。实际上,在C ++程序中,我建议不要使用它(起初我回答时曾提到C的引用,现在已被编辑掉了)。 - Francesco

0

内存分配有点像找停车位。 你在这里问的是,是否可以在停了几天的汽车上添加拖车。

答案是,在C语言中存在一个叫做realloc的函数,它允许你做以下事情。 如果我已经有足够的空间来添加我的拖车,那就加上。如果没有,就停在另一个足够大的地方,这相当于复制你的数据。

换句话说,你会遇到强烈和随机的性能问题。

那么在现实世界中你会怎么做呢?如果你知道你可能需要给你的车添加一些拖车,你可能会停在一个比所需空间大的地方。当超过所需空间时,你会将你的车和拖车移动到一个有足够空间留给未来拖车的地方。

这正是STL的string和vector为您做的事情。你甚至可以通过调用“reserve”来给它们一个关于未来拖车大小的提示。使用std::string可能是你问题的最佳解决方案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接