0

有一个

typedef struct person {
    char name[20]
    char surname[20]
} person_t;

我需要创建一个类似于XXXXXX:YYYYYY函数的字符串,如 char* personToString(person_t *p). 我试图做到:

char* personToString(person_t* p) {

  int n1,n2;
  n1=strlen(p->name);
  n2=strlen(p->surname);
  char *p = (char*) malloc((n1+n2+2)*sizeof(char));
  strcat(p,puser->name);
  strcat(p,":");
  strcat(p,puser->surname);

  return p;
}

这给了我一个合理的输出,但是我用 valgrind 测试了一些错误!我也认为有一种更优雅的方法来编写函数!

4

4 回答 4

3

当你 malloc 内存时p,内存将保存垃圾值。Strcat 将在空字符后附加一个字符串,但在未初始化的字符串中将包含随机值。

将第一个 strcat 替换为 strcpy。

于 2013-07-18T08:19:26.410 回答
3

你需要

strcpy(p,puser->name);

不是

strcat(p,puser->name);

malloc不会将缓冲区初始化为零,因此 strcat 首先在 p 中搜索一个空字节,并且可能找不到一个空字节,读取缓冲区的末尾并因此崩溃。

您还可以编写一个对 sprintf 的调用,而不是一个 strcpy 加两个 strcat:

sprintf(p, "%s:%s", puser->name, puser->surname);
于 2013-07-18T08:20:02.523 回答
2

首先你应该调用字符串复制,然后调用 strcat:

strcat(p,puser->name);

应该:

strcpy(p,puser->name);

因为使用 malloc 函数分配的内存会保留值垃圾,所以首先执行 strcat 是在垃圾之后连接 - 它还会在代码中带来未定义的行为。

您可以使用void* calloc (size_t num, size_t size);calloc 函数来代替 malloc() 初始化分配的内存0(然后 strcat() 没问题)。同样动态分配的内存,您应该使用显式释放内存块void free (void* ptr);)

于 2013-07-18T08:19:03.740 回答
2

这个我觉得不错

char* personToString( struct person_t *p )
{
  int len = strlen(p->name) + strlen(p->surname) + 2; // holds ':' + NULL 
  char *str = malloc( len ); // Never cast malloc's return value in C

  // Check str for NULL
  if( str == NULL )
  {
      // we are out of memory
      // handle errors
      return NULL;
  }

  snprintf( str, len, "%s:%s", p->name, p->surname);

  return str;
}

笔记:

  1. 永远不要malloc在 C 中强制转换 的返回值。
  2. snprintf在需要多个时使用strcat,它很优雅。
  3. free调用者中的返回值str

固定structchar可变

于 2013-07-18T08:26:55.647 回答