2016-03-31 6 views
1

私はArduinoのString.replace関数がrealloc()を使用していることを知っています。String.replace()と動的メモリ

私の「置換」機能は、charバッファを作成し、それを動的メモリ割り当ての点ではより良い入力文字列に割り当てますか?

私は最初に文字列を使用するべきではないことを知っていますが、当面はそれに固執しています。

これは私の関数である:

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; 
    } 
} 
+0

わからないが、私が思うには、 'char型のバフ[lenは];'いくつかのコンパイラでサポートされない場合があります。 – Pierre

+3

http://stackoverflow.com/questions/1887097/variable-length-arrays-in-c – manuell

+1

@Pierre:これはC++標準の一部ではなく、C99以降のCのみです。 – Aconcagua

答えて

1

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; 

はあまりにもすべての割り当てを行います。

オリジナルのStringは異なるメモリモデルでbufferを保持できません。動的割り当て済みのものはセンスがあります。

多くのCメモリモデル(スタックでは、静的、newによって割り当てられ、異なる場合はcallocによって割り当てられる)は、現実のライブラリでは減らされなければならない - 混合は危険である。例えば、スタック変数は長くは生きられません - 'allocated'にコピーする必要があります。

あなたは新しい可能性をチェックしますが、それは良いことですが、私はAconcaguaの実装の信頼に同意し、元のメモリモデルを置き換えません。

出典:https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/WString.cpp

EDITは:などconst引数に同意する...

0

効率の観点から、あなたはconst参照(String const& /*...*/)としてSUBINとsuboutを渡すことができ、これは、これら2つの文字列をコピーする避けることができます。

char buff[len]はC++ではサポートされていません。Cでは(C99以降)、eを参照してください。 g。 here。コンパイラーがスタック上の動的配列を拡張機能としてサポートしていない限り、ヒープ(新しいchar [len])–に配列を割り当てる必要があります。

in文字列のバッファを再利用しようとする可能性がありますが、置換文字列が置換文字列よりも長くない場合にのみ機能します(より正確には、文字列のバッファに収まる必要がありますコンテンツを保持するために内部的に割り当てられ、後者より長くなる可能性があります)。 に置き換える前に、置換する部品の後ろの文字列の一部(例えば、memmoveを使用)を移動する必要があります。

しかし、これはすべてStringクラスの内部を扱う必要があります(コンテンツのサイズや容量を調整するなど、バッファーを短すぎるためにバッファーを再割り当てする必要がある場合など)。汚れたハッキン​​グなしではアクセスできませんStringクラスが変更されるとすぐに破棄されます。

私の推奨事項:arduinoの実装を信頼してください。あなたが試していることを前提とするべきです:内部バッファーが結果全体を保持するのに十分な長さであれば、 0〜sのインデックス内の文字列を移動またはコピーする必要はなく、s + cからendまで適切に移動してからsuboutの内容をコピーする必要はありません)内部バッフアferはではなく、十分に長いです。ソースによって

関連する問題