【问题标题】:C: A safer way to check buffer in function and append to it?C: 一种更安全的方法来检查函数中的缓冲区并附加到它?
【发布时间】:2011-03-22 01:24:49
【问题描述】:

我有一个函数需要返回另一个日志记录函数的时间,它看起来像这样:

//put time in to buf, format 00:00:00\0
void gettimestr(char buf[9]) {
  if(strlen(buf) != 9) { //experimental error checking
    fprintf(stderr, "Buf appears to be %d bytes and not 9!\n", strlen( buf ));
  }
  time_t cur_time;
  time(&cur_time);
  struct tm *ts = localtime(&cur_time);
  sprintf(buf, "%02d:%02d:%02d",
        ts->tm_hour,
        ts->tm_min,
        ts->tm_sec );
  strncat(buf, "\0", 1);
}

现在我猜主要问题是检查缓冲区是否足够长,sizeof() 返回一个指针大小,而 strlen 似乎在两个不同的调用中随机返回 0 或诸如 12 之类的东西。

我的第一个问题是,我怎样才能安全地检测缓冲区的大小,这可能吗?

我的另一个问题是,接受 buf[9] 是一种有利的方法,还是应该接受指向缓冲区的指针,并使用 strcat() 而不是 sprintf() 来附加时间? sprintf 使时间值更容易填充零,尽管它似乎只接受字符数组而不接受指针。

【问题讨论】:

    标签: c pointers strcat error-checking arrays


    【解决方案1】:

    您的函数假定传入的缓冲区已经包含一个以空字符结尾的 9 个字符的字符串。这没有意义。

    正确的方法是请求大小作为参数:

    void gettimestr(char *buf, int bufferSize) {
    

    并使用 snprintf:

    snprintf(buf, bufferSize, "%02dx....", ....);<sub>*</sub>
    

    并终止字符串,因为如果您超出限制, snprintf 将不会这样做:

    buf[bufferSize-1] = 0;
    

    你可以这样调用你的函数:

    char buffer[16];
    gettimestr(buffer, sizeof(buffer));
    

    没有其他方法可以确定大小。这不是数组知道其大小的 Java。传递char * 只会将指针向下发送到函数而没有更多信息,因此获取缓冲区大小的唯一方法是要求调用者指定它。

    (编辑:如 cmets 中所指出的,snprintf 应始终正确终止字符串。)

    【讨论】:

    • 到目前为止,我对此的理解相当有限,感谢您的澄清。同时我还发现 strftime 可以替代手动 snprintf 虽然我更喜欢这个。
    • 不需要添加终止符 - snprintf() always 正确终止字符串(只要缓冲区长度至少为 1)。
    • @caf:是的。我想我曾经被不合规的 snprintf 实现烧死。
    • @caf:很好,也实现了。
    【解决方案2】:

    @EboMike 是对的。为了补充他的答案,您可以使用以下命令检查缓冲区:

    void gettimestr(char *buf, int bufferSize) {
        if (!buf) {
            fprintf(stderr, "Null buffer\n");
            return;
        }
    
     // rest of the code
    
     }
    

    【讨论】:

    • 最后,这是我需要对缓冲区进行的主要检查,调用者可以做许多我不需要在这个函数中检查的错误。谢谢。
    猜你喜欢
    • 2010-12-02
    • 1970-01-01
    • 1970-01-01
    • 2022-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-25
    • 1970-01-01
    相关资源
    最近更新 更多