-1
char* function (char* s)
{
    char buffer[1024];
    strcpy(buffer,s);
    buffer[strlen(s)-1]='\n';
    return buffer;
}

对于此功能,我认为此代码可能会失败的三件事:

  1. 如果 s 大于缓冲区,strcpy 会失败吗?
  2. 如果 s 为空,那么函数中的第三行会失败吗?
  3. 在多线程的情况下,这段代码会发生什么?它只会影响strcpy吗?(函数中的第二行)

你怎么看?还有更多可能失败的事情吗?我的假设之一错了吗?

谢谢

4

2 回答 2

1

就多线程而言,如果指向的内存s被另一个线程修改或变得无效(例如它被另一个线程释放),这个函数将无法正常工作。

于 2013-04-20T19:18:06.133 回答
0

首先,gcc-4.8 -Wall给你一个警告: function returns address of local variable

您不能有意义地返回本地数组(或字符串)。至少,声明它static(但这不是多线程友好的)。

然后,strcpy应该if (s) strncpy(buffer, s, sizeof(buffer))避免缓冲区溢出,并避免取消引用空指针(如果s == NULL)。

并且您想在换行符之后将字符串归零,因此编写类似的代码

size_t slen = s?strlen(s):0;
if (slen>=sizeof(bufber)-1) slen=sizeof(bufber)-2;
memcpy(buf, s, slen);
buffer[slen-1] = '\n';
buffer[slen] = (char)0;

除非buffer是静态的,否则您希望return strdup(buffer);调用者应确保它free稍后变为 -d。

真的想要 strdup或者最好是 asprintf

char* addnewline(const char*s)
{
   char* dynbuf = NULL;
   if (!s) return NULL;
   asprintf(&dynbuf, "%s\n", s);
   return dynbuf;
}

具有重要约定调用者addnewline应确保结果为free-d

您应该返回堆分配的内存,并且您应该有一个约定来定义谁将释放它。

您甚至可以使用Boehm 的 GC,即它GC_strdup而不用费心释放自己的结果。

如果你不想使用asprintf,因为它只是 GNU,那么代码

char* addnewline(const char*s) {
  if (!s) return NULL;
  size_t sz = strlen(s);
  char* dynbuf = malloc(sz+2);
  if (!dynbuf) { perror("addnewline malloc"); exit(EXIT_FAILURE); };
  memcpy(dynbuf, s, sz);
  dynbuf[sz] = '\n';
  dynbuf[sz+1] = (char)0;
  return dynbuf;
}

但是您确实希望结果addnewline是堆分配的约定,并且应该free在调用后使用 -d 。

于 2013-04-20T19:00:26.983 回答