3

文字列バッファを意図したプログラムで問題が発生しています。具体的には、この関数は文字列 cstr でバッファをリセットすることを目的としています。cstr が null の場合、コンテンツを空の文字 '\0' にリセットする必要があります。buf->contents のサイズを変更している realloc の 2 番目のセットで常にハングします。その理由はわかりません。どんな助けでも素晴らしいでしょう。

構造体:

typedef struct strbuf {
     char   *contents;
     size_t  length;  
} StringBuffer;

から呼び出されます。

strbuf_reset(sb, NULL)

問題が発生している strbuf_reset 関数を次に示します。

StringBuffer *strbuf_reset(StringBuffer *buf, const char *cstr)
{
if(buf == NULL)
    return NULL;

StringBuffer *tempBuf = NULL ;

if(cstr == NULL)
    tempBuf = (StringBuffer*)realloc(buf,sizeof(StringBuffer) + sizeof(char));
else
    tempBuf = (StringBuffer*)realloc(buf,sizeof(buf) + strlen(cstr)*sizeof(char));

if(tempBuf == NULL)
    return NULL;

if(cstr == NULL)
    tempBuf->contents = (char*)realloc(buf->contents,sizeof(char));
else
    tempBuf->contents = (char*)realloc(buf->contents,(sizeof(buf->contents) + strlen(cstr)*sizeof(char) + 1));

if(tempBuf->contents == NULL){
    free(tempBuf);
    return NULL;
}
buf = tempBuf;

if(cstr == NULL)
   buf->contents = '\0';
else
   strcat(buf->contents,cstr);

buf->length = strlen(buf->contents);    

return buf;
 }

提案された変更であると私が信じているもので...

StringBuffer *strbuf_reset(StringBuffer *buf, const char *cstr)
{
if(buf == NULL)
    return NULL;

StringBuffer *tempBuf = NULL ;

if(cstr == NULL)
    tempBuf = (StringBuffer*)realloc(buf,sizeof(StringBuffer) + sizeof(char) + 10);
else
    tempBuf = (StringBuffer*)realloc(buf,sizeof(buf) + strlen(cstr)*sizeof(char)+ 1);

if(tempBuf != NULL)
    buf = tempBuf;
else
    return NULL;    

if(cstr == NULL)
    tempBuf->contents = (StringBuffer*)realloc(buf->contents,sizeof(StringBuffer) + sizeof(char) + 10);
else
    tempBuf->contents = (StringBuffer*)realloc(buf->contents,sizeof(buf) + strlen(cstr)*sizeof(char)+ 1);

if(tempBuf != NULL)
    buf->contents = tempBuf->contents;
else
    return NULL;

if(cstr == NULL)
   buf->contents = '\0';
else
   strcat(buf->contents,cstr);

buf->length = strlen(buf->contents);    

return buf;
 }
4

3 に答える 3

7

あなたは何が何をするのか理解していないようですrealloc

それについて考える必要がある方法(少なくとも拡大に関する限り) は、新しいバッファーを割り当て、古いデータをそこにコピーしてから、古いバッファーを解放することです。

古いポインターは無効になり、後でもう一度使用しようとするとクラッシュしても驚くことではありません。

返された値をすぐに古いポインターに割り当てる必要があるため、有効なデータを指しています。

于 2010-06-29T01:01:19.123 に答える
1

StringBufferの内容を上書きするので、reallocを使用しても意味がありません。メモリ割り当ては保存されませんが、代わりに、とにかく上書きする予定の古いデータがコピーされます。通常のmallocを使用して無料で使用します。

元の構造で

typedef struct strbuf {
  char   *contents;
  size_t  length;  
} StringBuffer;

strbuf_resetはbufをcstrに設定します。成功するとbufを返し、失敗するとNULLを返します。

StringBuffer *strbuf_reset(StringBuffer *buf, const char *cstr)
{
  if (!buf)  return NULL;      
  if (!cstr)  cstr = "";

  size_t len = strlen(cstr);
  if (len > buf->length) {
    char *new_contents = malloc(len + 1);
    if (!new_contents)  return NULL;
    free(buf->contents);
    buf->contents = new_contents;
  }
  memcpy(buf->contents, cstr, len + 1);
  buf->length = len;

  return buf;
}
于 2010-06-29T01:46:51.553 に答える
1

StringBuffer 内の文字列に余分なスペースを割り当てています。buf->contents は、余分に割り当てられたスペースを指していると想定しました。これが正しくない場合、なぜ StringBuffer に余分なスペースが割り当てられるのでしょうか?

buf->contents が StringBuffer に割り当てられたメモリを既に指している場合、再割り当てを試みると、割り当てられていないポインタを再割り当てすることになるため、メモリ システムがクラッシュ/ハング/破損したヒープの状況に陥ります。

buf->contents を再割り当てしようとする代わりに、構造は次のようになるはずです。

struct StringBuffer {
    size_t length;
    char contents[1];
};

次に、buf->contents を再割り当てする代わりに、そこに文字列をコピーするだけで、StringBuffer の再割り当てがすべてのメモリを処理します。

于 2010-06-29T01:02:24.833 に答える