2016-04-17 7 views
-1

私の機能では、部分文字列を置き換えます。入力部分文字列が元の部分文字列よりも長い場合は、入力文字列の一部を移動して入力部分文字列のためのスペースを確保します。realloc()を使用してmemmove()を安全にする

この結果、未定義の動作が発生することがわかりました。私はrealloc()を使って必要なスペースを割り当てることができるはずだが成功していないと思った。

I)は、(MEMMOVE前にこれを追加してみました:

char *newspc = (char*)realloc(in,len+sublen); 
in = newspc; 

これは合理的な戦略ですか?この操作のためのスペースを作る正しい方法は何ですか?あなたがのreallocを使用したい場合、あなたはreallocのは、データをコピーするの世話をするために、MEMMOVEを使用する必要はありません、

#include <iostream> 
#include <string> 
#include <string.h> 

void replc(char* in, char* subin); 

int main() 
{ 
    char stmt[] = "replacing this $string ok"; 
    std::cout << stmt << "\n"; 
    replc(stmt, "longerstring"); //<<<4 characters longer breaks the program 
    std::cout << stmt << "\n"; 

} 

void replc(char* in, char* subin){ 
    uint8_t len = strlen(in); 
    uint8_t aftok = strchr(strchr(in, '$'), ' ')-in; 
    uint8_t dollar = strchr(in, '$')-in; 
    uint8_t tklen = aftok - dollar; 
    uint8_t sublen = strlen(subin); 

    if(sublen <= tklen){ 
    //enough room for substring 
    memmove(in+aftok-(tklen-sublen), in+aftok, (tklen-sublen)+1); 
    memcpy(in+dollar, subin, sublen); 
    in[len-(tklen-sublen)] = '\0'; 
    } 
    else{ 
    //not enough room for substring 
    // memory allocation should take place here? 
    memmove(in+aftok+(sublen-tklen), in+aftok, (sublen-tklen)+1); 
    memcpy(in+dollar, subin, sublen); 
    in[len+(sublen-tklen)] = '\0'; 
    } 

} 
+2

*文字列の外側のインデックスは、割り当てられていないメモリであると考えました。入力部分文字列の長さを数文字だけ増やしても、プログラムは失敗します。* - 未定義の動作、単純で単純です。境界を超えて配列にアクセスすると、「仕事」を含む何かが起こります。 – PaulMcKenzie

+0

私はそのリンクに照らして質問を変えました。 – oraz

+1

これに 'std :: string'を使わないのはなぜですか?私はあなたが最終的にこの問題を解決するための "魔法のコード"を理解しようとしていることを知っています。バッファとポインタを使ってやるだけです。しかし、バグを修正する以外は、あなたはそれから何を得るのですか?あなたの時間を評価するなら 'std :: string'を使ってください。あなたは ''も含めましたが、何も使っていませんでした。 – PaulMcKenzie

答えて

1

まず:ここ

はreallocのを使用せずにプログラム()です。 manから

のrealloc()関数は、メモリブロックのサイズを変更は、サイズバイトにptrが を指摘しました。内容は、 から領域の開始までの範囲で、古いサイズと新しいサイズの最小値まで変更されません。

また、あなただけ)ptrがNULLでない限り、それはmalloc関数(への以前の呼び出しで返されている必要があります以前のmalloc、reallocの、またはのcalloc

によって返されたポインタ上のreallocを使用することができます、のcalloc ()またはrealloc()を呼び出します。

だから、あなたは、呼び出し元の関数にポインタの値を変更したい場合は、そのポインタ(Cスタイルにポインタを使用する必要がある、あなたの主な

char *stmt = malloc(strlen("replacing this $string ok") + 1); 
if (stmt) 
    stmt = "replacing this $string ok"; 

第二にmalloc関数を使用する必要があります)または参照(C++スタイル)でなければ、呼び出し元のポインタは古いアドレスを指します。

プロトタイプ用

Cスタイルの例:(整数としてNewSizeパラメータを有する)

void replc(char** in, char* subin); 

配分:

*in = realloc(*in, NewSize); 

(割り当てが失敗した場合mallocとのreallocはNULLを返すことができることに注意してください)

+0

-alloc関数について知るにはいくつかのことがあったようですが、これが助けになりました。私が使用したパラメータは ''(char *&in、... '' char * p =(char *)calloc(len + sublen、sizeof(char)); – oraz

関連する問題