3

ご覧いただきありがとうございます。無視してください- あらゆる種類のシェナニガンが発生しており、さらにデバッグしようとしています。

=====================================

realloc のこの動作を説明できる人はいますか?

出力:

before realloc start: testing%20encryp
before realloc app: '          '
realloc size: 27
after realloc: testing%20e
strlen(newstr): 11
newstr: testing%20e

コード:

char * strAppend(char * start, char * app)
{
  int i=strlen(start);
  int j=0;
  printf("before realloc start: %s\n", start);
  printf("before realloc app: '%s'\n", app);
  printf("realloc size: %i\n", i+strlen(app)+1);
  char * newstr = realloc(start, sizeof(char) * (i + strlen(app) + 1));
  printf("after realloc: %s\n", newstr);
  while(app[j] != '\0')
    newstr[i++] = app[j++];
  printf("strlen(newstr): %i\n", strlen(newstr));
  printf("newstr: %s\n", newstr);
  return newstr; }

再割り当て後に最初から「ncryp」を削除しています。しかし、それは起こるはずがありません....

編集:より多くのコード、より多くの出力

char * urlEncode(char * c)
{
#ifdef EBUG
  printf("urlEncode: Encoding '%s'\n", c);
#endif
  int len = strlen(c)+1;
  char * ret = malloc(sizeof(char) * len);
  memset(ret, 0, len);
  int z=0;
  char * escapee = malloc(sizeof(char) * 4);
  escapee[0] = '%'; escapee[3] = '\0';
  for(int i=0;i<strlen(c);i++)
    {
      printf("z = %i len = %i ret = %s\n", z, len, ret);
      if(z >= len)
        {
          ret = strAppend(ret, "          ");
          len += strlen("          ");
        }
      printf("z = %i len = %i ret = %s\n", z, len, ret);
      if ( (48 <= c[i] && c[i] <= 57) ||//0-9
           (65 <= c[i] && c[i] <= 90) ||//abc...xyz
           (97 <= c[i] && c[i] <= 122) || //ABC...XYZ
           (c[i]=='~' || c[i]=='!' || c[i]=='*' || c[i]=='(' || c[i]==')' || c[i]=='\'')
           )
        {
          ret[z++] = c[i];
        }
      else
        {
          char2hex(c[i], escapee);
          ret = strAppend(ret, escapee);
          z += 3;
        }
    }
  ret[z] = '\0';
  free(escapee);
#ifdef EBUG
  printf("urlEncode: Encoded string to '%s'\n", c);
#endif
  return ret;
}




urlEncode: Encoding 'testing encrypt'
z = 0 len = 16 ret =
z = 0 len = 16 ret =
z = 1 len = 16 ret = t
z = 1 len = 16 ret = t
z = 2 len = 16 ret = te
z = 2 len = 16 ret = te
z = 3 len = 16 ret = tes
z = 3 len = 16 ret = tes
z = 4 len = 16 ret = test
z = 4 len = 16 ret = test
z = 5 len = 16 ret = testi
z = 5 len = 16 ret = testi
z = 6 len = 16 ret = testin
z = 6 len = 16 ret = testin
z = 7 len = 16 ret = testing
z = 7 len = 16 ret = testing
before realloc start: testing
before realloc app: '%20'
realloc size: 11
after realloc: testing
strlen(newstr): 10
newstr: testing%20
z = 10 len = 16 ret = testing%20
z = 10 len = 16 ret = testing%20
z = 11 len = 16 ret = testing%20e
z = 11 len = 16 ret = testing%20e
z = 12 len = 16 ret = testing%20en
z = 12 len = 16 ret = testing%20en
z = 13 len = 16 ret = testing%20enc
z = 13 len = 16 ret = testing%20enc
z = 14 len = 16 ret = testing%20encr
z = 14 len = 16 ret = testing%20encr
z = 15 len = 16 ret = testing%20encry
z = 15 len = 16 ret = testing%20encry
z = 16 len = 16 ret = testing%20encryp
before realloc start: testing%20encryp
before realloc app: '          '
realloc size: 27
after realloc: testing%20encryp
strlen(newstr): 26
newstr: testing%20encryp
z = 16 len = 26 ret = testing%20encryp

最終編集:

現時点で何が起こっているのかわかりません。デバッグ フラグを使用するプログラムと使用しないプログラムを実行すると、異なる出力が生成されます。設計図に戻り、valgrind を使用してメモリ エラーを探します。

4

4 に答える 4

1

への最初のパラメータは、以前に,またはによって返され、その後dによって返されなかっreallocたポインタでなければなりません。malloccallocreallocfree

そうでなければ、あなたが見たものを含め、何かが起こるかもしれません.

どこstartから来たの?

編集:編集を投稿してください。再割り当ての問題はないようです。

于 2009-08-01T17:20:16.113 に答える
1

あなたがやろうとしているのは、start と app の 2 つの文字列を連結することだと思います。この場合は、strncat 関数を使用することをお勧めします。

#include <cstring>
char *strncat( char *str1, const char *str2, size_t count );
于 2009-08-01T17:23:14.607 に答える
1

元の realloc の問題は再現できなかったようですので、探していることを実行する少しリファクタリングされたコードをあえて投稿します。文字列に対して 2 つのパスを作成しますが、私の意見では、実行されるメモリ割り当て呼び出しの数に関して、より予測可能なパフォーマンスが得られるはずです (1 回のみ)。また、あなたのものより少し短いです。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int is_printable(char c) {
 return (48 <= c && c <= 57) ||//0-9
        (65 <= c && c <= 90) ||//abc...xyz
        (97 <= c && c <= 122) || //ABC...XYZ
        c == '~' || c =='!' || c== '*' ||
        c == '(' || c== ')' || c== '\'';
}

char *urlEncode(char *s) {
  char *ret, *c, *ct;
  int i, len;
  printf("urlEncode: Encoding '%s'\n", s);
  /* First pass - figure out how long the target string should be */
  len = 0;
  for(c=s; *c; c++) {
    if(is_printable(*c)) len++; else len += 3;
  }
  /* Don't forget we need to store terminating zero too */
  len++;
  printf("Current len: %d, target len: %d\n", strlen(s)+1, len);
  ct = ret = malloc(len);
  /* Second pass - copy/encode */
  for(c=s; *c; c++) {
    if(is_printable(*c)) {
      *ct++ = *c;
    } else {
      snprintf(ct, 4, "%%%02x", *c);
      ct += 3;
    }
  }
  *ct = 0; /* null-terminate the string */
  printf("Encoded string: %s\n", ret);
  return ret;
}

int main(int argc, char *argv[])
{
  urlEncode("testing encrypt");
  exit(1);
}
于 2009-08-01T18:00:16.733 に答える
0
char * strAppend(char * start, char * app)
{
  int i=strlen(start);
  int j=0;
  printf("before realloc start: %s\n", start);
  printf("before realloc app: '%s'\n", app);
  printf("realloc size: %i\n", i+strlen(app)+1);
  char * newstr =(void*) realloc(start, sizeof(char) * (i + strlen(app) + 1));


  memset(newstr,'z',sizeof(char) * (i + strlen(app) + 1));
  printf("addres  %x\n",newstr);

  printf("after realloc: %s\n", newstr);
  while(app[j] != '\0')
    newstr[i++] = app[j++];

    //missing null terminating character
    newstr[i]=0;

  printf("strlen(newstr): %i\n", strlen(newstr));
  printf("newstr: %s\n", newstr);
  return newstr; 
  }

私のシステムでは、割り当てられた文字列newstrのアドレスは、「開始」の割り当てられたサイズに関係なく、開始と同じです。明らかに、システムはメモリが大きくなると同じ位置を再割り当てしています

于 2009-10-25T15:05:39.820 に答える