【问题标题】:Seg fault with time and ctime, when porting from Linux to OSX从 Linux 移植到 OSX 时,时间和 ctime 出现段错误
【发布时间】:2011-06-29 18:47:33
【问题描述】:

我在编译为(我相信)OSX 上的 Linux 设计的代码时遇到错误。我已将问题追溯到这部分代码:

TIMEVAL = time(NULL);
char* TIMESTRING = ctime(&TIMEVAL);
TIMESTRING[24]=' ';

fprintf(LOG, "[ %20s] ", TIMESTRING);

有什么理由会出现这种情况吗?我已经加入了<time.h>

【问题讨论】:

  • 由于遇到分段错误,请检查TIMESTRING[24] 是否有效。

标签: c time segmentation-fault ctime


【解决方案1】:

ctime 正在使用特定大小的静态分配缓冲区,因此您的第一个问题是您在不知道大小的情况下附加到该字符串。

TIMESTRING[24]=' ';

如果缓冲区只有 24 个字节,这可能会导致它自己的段错误。另一个原因可能是,如果零终止恰好在索引 24 处,您刚刚使字符串未终止,fprintf 将继续读取,直到它到达不允许读取的内存,从而导致段错误。

如果您想修改ctime_r 和预分配的缓冲区,请确保缓冲区足够大以容纳您的数据,并且在完成后以零结尾。如果ctime_r 不可用,请在修改之前对自己的缓冲区执行strncpy

HTH

编辑

我不确定您到底想要做什么,但假设您发布的代码是直接从您的应用程序中获取的,那么您实际上可能希望这样做:

TIMEVAL = time(NULL);
char* TIMESTRING = ctime(&TIMEVAL);

fprintf(LOG, "[ %20s ] ", TIMESTRING);

也就是说,填充您的时间字符串。只需在格式字符串中添加空格,而不是在时间字符串缓冲区中。

【讨论】:

  • 太棒了,谢谢。这很好地解决了问题,我现在明白他们最初想要做什么......
  • 我现在收到一些警告,但它们似乎来自 ctime/time 调用本身。我已经发布了一个关于此stackoverflow.com/questions/5041374/… 的单独问题
【解决方案2】:

以此为例,ctime 返回的是 Sat May 20 15:21:51 2010,它只有 24 个字符(即 24 个字节)。因此,您的数组索引从 0 到 23 开始。因此,在索引 24 处,它具有终止字符。

所以,TIMESTRING[24]=' ';错误(即,您将终止字符替换为空格字符)并导致您在后期出现分段错误。

【讨论】:

  • 实际上,null 终止在索引 24 处,导致字符串未终止。然后fread 将触发故障。写入本身不会导致它。
  • @roe - 是的,我们可以访问终止字符,但不应修改它。对不对?
  • 你是对的,在这种情况下这样做是错误的,但是“没有索引 24”是不正确的。如果你碰巧知道分配的缓冲区比这个大,添加更多字符,覆盖空值是完全可以的,只要确保你在最后附加一个空值。问题是您不确定该缓冲区有多大,因为它是 ctime 的实现细节并且可能会有所不同。此外,如果您知道字符串的长度,则不必将字符串作为以空字符结尾的字符串。大多数库函数都假设它们是。
  • @roe - 感谢您的详细解释。相应地修改了我的答案描述。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-08
  • 1970-01-01
  • 2014-06-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-22
相关资源
最近更新 更多