Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ String.replace()和动态内存_C++_Arduino - Fatal编程技术网

C++ String.replace()和动态内存

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) {

我知道Arduino的String.replace函数使用realloc()

在动态内存分配方面,我的“替换”函数(它构建一个字符缓冲区,然后将其分配给输入字符串)是否更好

我知道我一开始不应该使用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] = '\0';
     in = buff; 
    }
}

从效率的角度来看,可以将subin和subout作为常量引用传递(
stringconst&/*…*/
),这样可以避免复制这两个字符串

Cububuff [Le] 不支持C++,只在C(从C99 on)中,参见E。G您必须在堆上分配数组(new char[len])——除非编译器支持堆栈上的动态数组作为扩展

然后您可以尝试重用字符串中
的缓冲区,但是,只有当替换字符串的长度不超过要替换的字符串时(更准确地说:较长的部分必须适合内部分配的字符串缓冲区,以容纳内容,并且可能比后者长)。在插入替换项之前,您必须在要替换的部分之后移动字符串的部分(例如,使用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++中的可变长度数组”?