我使用g++
工具链v4.9.2在Solaris 10上构建了C ++代码库。此代码库正在移植到Linux 64位。我正在面对由SIGSEGV
引起的奇怪的运行时核心转储,同时显然是无辜的呼叫strftime
。 API strftime
具有以下签名:
size_t strftime(char *s, size_t max, const char *format,
const struct tm *tm);
众所周知,size_t
在64位可执行文件上是64-bit (unsigned long)
,而在32位系统上是32位。
我有一些功能如下:
void somefunc(X *& p)
{
p = new X[20000];
// p gets allocated and have a decent pointer value
char s[30];
time_t t = time(NULL);
struct tm *tmp = localtime(&t);
strftime(s, 30, "%Y %m %d %T", tmp); // apparently innocent call
// after this, p gets garbled and access to p cause crash
}
32位Solaris系统上的相同代码运行完全正常,但在Linux-64位上导致运行时内存损坏。
只是一个嫌疑人,size_t的大小是8字节对4字节可能是一个问题?例如,仅举一个类比,在做简单的printf
时,32位size_t
需要%d
作为格式说明符,而64位size_t
则需要{{1}作为格式说明符。 strftime格式化也存在类似的原因吗?
另一个线索,如果我注释掉strftime语句,代码在64位上运行正常。
听起来很特别,令人惊讶。请思考。