Thursday, January 21, 2010

**作为C函数参数(2)

之前写了一篇<<**作为C函数参数>>的文章。 今天又看到这个样的代码。 不过, 比之前的多一点需要注意的地方
在glibc/login/login.c代码里:
static int
tty_name (int fd, char **tty, size_t buf_len)
{
.....((被切掉).....

  if (rv == 0)
    /*
      这里 *tty = buf已经修改了tty这个变量指向的空间.
      为什么不在改变前把传入的空间free掉呢?如:
      如果不free掉, 使用这个函数前需要有另外一个变量引用这块空间
      不用调用free, 是因为login里, _tty是一个局部变量, 会在函数退出后自己释放
    */
    *tty = buf;   /* Return buffer to the user.  */
  else if (buf != *tty)
    free (buf);   /* Free what we malloced when returning an error.  */

  return rv;
}

作者还是清楚的:

#ifdef PATH_MAX
  char _tty[PATH_MAX + UT_LINESIZE];
#else
  char _tty[512 + UT_LINESIZE];
#endif
  char *tty = _tty;
.....
found_tty = tty_name (STDIN_FILENO, &tty, sizeof (_tty));

看出, 有两个变量指向那块空间. 还是数组, 安全得很呢.

因此, 如果**作为参数时:
1. 如果在函数内, 改变了**指向的内存, 这时, **不是指向通过malloc得到的内存是安全的
2. 否则, 请确保还有其它变量引用之

如:

int len = 100;
char *name = (char *)malloc( len );
char * other = name;
tty_name (1, &name, len)

或者是:

char name[100];
char *new = name;
tty_name (1, &new, sizeof( name ));

这种做法:
char name[100];

char *new = name;

可以像malloc一样得到内存, 但是它比较安全: 会自动根据变量的作用范围释放使用的内存.

这种细节, 处理又麻烦, 不处理又不对. 纠结.... 需要长期的code能力.

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.