String.replace() and dynamic memory
我知道Arduino的string.replace函数使用realloc()。
我的"replacement"函数构建了一个char缓冲区,然后将其分配给输入字符串,在动态内存分配方面是否更好?
我知道我不应该一开始就用绳子,但我暂时还坚持着。
这是我的职责:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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; } } |
根据消息来源
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | 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; } |
你的一行作业
1 | in = buff; |
号
也进行所有分配。
必须这样做,原来的
从广泛的角度来看,现实生活中的许多C内存模型(堆栈、静态、由
您检查了新的可能性,这很好,但我同意Aconcagua在实现方面的信任,而不是替换原始的内存模型。
资料来源:https://github.com/arduino/arduino/blob/master/hardware/arduino/avr/cores/arduino/wstring.cpp
编辑:同意
从效率的角度来看,可以将subin和subout作为const引用(
在C++中不支持EDOCX1 1,仅在C(从C99上),参见这里。除非编译器支持堆栈上的动态数组作为扩展名,否则必须在堆上分配数组(new char[len])。
然后,您可以尝试重用
然而,所有这些都需要处理字符串类的内部(包括调整内容的大小和可能的容量,如果由于太短而不得不重新分配自己的缓冲区),那么在没有脏的黑客的情况下,您无法访问这些黑客,这些黑客会在字符串类更改后立即中断……
我的建议:相信Arduino的实现——你应该假设它已经实现了你正在尝试的:如果内部缓冲区足够长,能够容纳整个结果,那么它将被使用(不需要在索引0-S中移动或复制字符串,将部分从S+C适当地移动到末尾,然后在子输出的内容中复制)一个d只有在内部缓冲区不够长时才使用重新分配。