C++ String.replace()和动态内存
我知道Arduino的String.replace函数使用realloc() 在动态内存分配方面,我的“替换”函数(它构建一个字符缓冲区,然后将其分配给输入字符串)是否更好 我知道我一开始不应该使用String,但我现在一直在使用它 这是我的职责:C++ String.replace()和动态内存,c++,arduino,C++,Arduino,我知道Arduino的String.replace函数使用realloc() 在动态内存分配方面,我的“替换”函数(它构建一个字符缓冲区,然后将其分配给输入字符串)是否更好 我知道我一开始不应该使用String,但我现在一直在使用它 这是我的职责: void replaceSubstr(String& in, String subin, String subout){ int s = in.indexOf(subin); if(s > -1) {
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] = '\0';
in = buff;
}
}
从效率的角度来看,可以将subin和subout作为常量引用传递(
stringconst&/*…*/
),这样可以避免复制这两个字符串
的缓冲区,但是,只有当替换字符串的长度不超过要替换的字符串时(更准确地说:较长的部分必须适合内部分配的字符串缓冲区,以容纳内容,并且可能比后者长)。在插入替换项之前,您必须在要替换的部分之后移动字符串的部分(例如,使用memmove)
然而,所有这一切都需要处理String类的内部(包括调整内容的大小和可能的容量,如果你因为太短而不得不重新分配缓冲区),如果没有肮脏的黑客攻击,你将无法访问它,一旦String类发生变化,这些黑客攻击将立即中断
我的建议:相信arduino的实现——您应该假设它已经完成了您正在尝试的工作:如果内部缓冲区足够长,可以保存整个结果,那么将使用它(不需要移动或复制索引0-s中的字符串,将部分从s+c移动到适当的结尾,然后复制子输出的内容)如果内部缓冲区不够长,则仅使用重新分配 来源
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;
也会分配所有的资源
必须这样做,原始的字符串
不能在不同的内存模型中保存缓冲区
,只有一个“动态分配”有意义
从广泛的角度来看,许多C内存模型(堆栈、静态、由new
分配、由calloc
分配,如果它们不同)必须在现实生活中的库中减少-混合是危险的。例如,堆栈变量不能生存更长时间-必须复制到“已分配”
您检查了新的可能性,这很好,但我同意Aconcagua对实现的信任,而不是取代原来的内存模型
资料来源:
编辑:同意const
参数等…不确定,但我认为charbuff[len]代码>可能不受编译器的支持。您可能想读取@彼埃尔:这不是C++标准的一部分,只有C99以来才有C。@ AccCuAGA您读过吗?@ AccCuGaa“C++中的可变长度数组”?