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

to 的第一个参数realloc必须是先前由 d 返回的指针malloccalloc或者realloc不是随后freed 返回的指针。

如果不是这种情况,任何事情都可能发生,包括您所看到的。

从哪里来start

编辑:发布您的编辑,您似乎没有重新分配问题!

于 2009-08-01T17:20:16.113 回答
1

我认为您要做的是连接两个字符串 start & app,如果是这种情况,您最好使用 strncat 函数

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

由于您最初的 realloc 问题似乎无法重现,我敢于发布一个稍微重构的代码,它可以满足您的需求。它对字符串进行了两次传递,但在我看来,就执行的内存分配调用数量而言,它应该具有更可预测的性能 - 仅一次。它也比你的短一点。

#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; 
  }

and in my system the address of the allocated string newstr is equal to start no matter what is the allocated size of 'start', aparently the system is reallocating the same position of the memory when it grows

于 2009-10-25T15:05:39.820 回答