String.replace() 和动态内存
String.replace() and dynamic memory
我知道Arduino的String.replace 函数使用 realloc((。
我的"替换"函数,它构建一个 char 缓冲区,然后将其分配给输入字符串,在动态内存分配方面是否更好?
我知道我不应该首先使用 String,但我暂时坚持使用它。
这是我的函数:
void replaceSubstr(String& in, String subin, String subout){
int s = in.indexOf(subin);
if(s > -1)
{
int a = in.length();
int b = subout.length();
int c = subin.length();
int len = (a + (b - c))+1;
char buff[len];
memcpy(buff, in.c_str(), s);
memcpy(&buff[s], subout.c_str(), b);
memcpy(&buff[s+b], in.substring(s+c).c_str(), a-(s+c));
buff[len-1] = ' ';
in = buff;
}
}
按来源
String::String(const char *cstr)
{
init();
if (cstr) copy(cstr, strlen(cstr));
}
...
inline void String::init(void)
{
buffer = NULL;
capacity = 0;
len = 0;
}
...
String & String::copy(const char *cstr, unsigned int length)
{
if (!reserve(length)) {
invalidate();
return *this;
}
len = length;
strcpy(buffer, cstr);
return *this;
}
...
void String::invalidate(void)
{
if (buffer) free(buffer);
buffer = NULL;
capacity = len = 0;
}
...
unsigned char String::reserve(unsigned int size)
{
if (buffer && capacity >= size) return 1;
if (changeBuffer(size)) {
if (len == 0) buffer[0] = 0;
return 1;
}
return 0;
}
您的单行分配
in = buff;
也进行所有分配。
必须这样做,原始String
不能在不同的内存模型中保存buffer
,只有一个"动态分配"有意义。
从广义上讲,许多C内存模型(堆栈,静态,由new
分配,如果它们不同,则由calloc
分配(必须在现实生活中减少 - 混合是危险的。例如,堆栈变量不能存活更长时间 - 必须复制到"已分配"。
你检查新的可能性,这很好,但我同意Aconcagua对实现的信任,而不是取代原始的内存模型。
资料来源:https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/WString.cpp
编辑:同意const
论点等...
从效率的角度来看,您可以将 subin 和 subout 作为常量引用 (String const& /*...*/
( 传递,这样可以避免复制这两个字符串。
char buff[len]
在C++中不受支持,仅在 C 中受支持(从 C99 开始(,请参阅此处。您必须在堆上分配数组(new char[len](——除非您的编译器支持堆栈上的动态数组作为扩展。
然后,您可以尝试重用in
字符串的缓冲区,但是,这仅在替换字符串不长于要替换的字符串时才有效(更准确地说:较长的部分必须适合内部分配的字符串缓冲区以保存内容,并且可能比后者长(。在插入替换部分之前,您必须将字符串的一部分移动到要替换的部分之后(例如使用 memmove(。
然而,所有这些都需要处理 String 类的内部(包括例如调整内容的大小和可能的容量,如果您由于太短而不得不重新分配缓冲区(,如果没有肮脏的黑客,您将无法访问,一旦 String 类更改就会中断......
我的建议:相信 arduino 的实现 - 你应该假设它已经完成了你正在尝试的事情:如果内部缓冲区足够长以保存整个结果,它将被使用(不需要移动或复制索引 0-s 中的字符串,适当地将部分从 s+c 移动到末尾,然后复制 subout 的内容(并且只使用 repositionate, 如果内部缓冲区不够长。
- 在以唯一ptr为值的C++映射中,动态内存何时会被销毁
- 开放 CV 中的动态内存分配,用于视频处理
- 为什么类和 main() 函数中也有动态内存分配
- 在没有动态内存的世界中,我是否需要虚拟析构函数?
- c++ 动态内存 堆栈中的分配
- 给定特定内存地址的数组的动态内存分配
- 释放动态内存时C++错误
- 我刚刚了解了C++中的动态内存分配
- 无法删除布尔动态内存分配
- 有没有办法找到动态内存大小,比如大小?
- 我在 2D 数组的动态内存分配中遇到了一些奇怪的代码C++? 请解释一下这是什么?
- 具有对齐存储的动态内存分配
- 指向数组unique_ptr在调用 release() 后会自动释放动态内存,这是真的吗?
- 在cpp中使用boost-python的python代码是否进行动态内存分配
- 我应该在这个程序中使用静态内存分配还是动态内存分配
- C++ 模板函数中的动态内存分配
- 指向动态内存中结构中的变量时出现问题
- C++具有动态内存分配的 constexpr 函数
- 动态内存分配错误
- 按引用传递和动态内存分配之间的区别是什么