【发布时间】:2012-12-13 06:01:57
【问题描述】:
这是来自 gdb:
22 database->size = size;
(gdb) n
23 return database;
(gdb) p size
$6 = 1401
(gdb) p database->size
$7 = 3086862424
(gdb) p &size
$8 = (unsigned int *) 0xbffff050
(gdb) p &database->size
$9 = (unsigned int *) 0xb7fc6ff8
这是来自代码:
typedef struct _DATABASE {
RESULT* res;
unsigned int size;
} DATABASE;
....
....
DATABASE* alloc_database(unsigned int size, DATABASE* database)
{
database = (DATABASE*) malloc (sizeof(DATABASE));
if (!database) return NULL;
database->res = (RESULT*) malloc (sizeof(RESULT) * size);
if (!database->res) {
free_database(database);
return NULL;
}
memset(database->res, 0, sizeof(RESULT) * size);
database->size = size;
return database;
}
你可以看到,database->size 和 size 都来自 (unsigned int) 类型,在代码和 gdb 中,但由于某种原因,赋值后的值不同。
有人知道这是什么原因吗?
【问题讨论】:
-
听说过
calloc()吗?它确实在一个函数调用中分配和归零——并且可以使用最有效的归零,因为它知道数据在memset()没有对齐的地方对齐。 -
你确定你的代码是在没有优化的情况下编译的吗?
-
调用函数长什么样子?
-
@JonathanLeffler:我不认为对齐是
calloc擅长的地方;memset中唯一重要的位置错位开销是n的微小值,其中启动开销占主导地位。对于大的n,它会迷失在噪音中。calloc真正的性能优势在于它有时可以知道内存已预置零(例如,当通过新的mmap获得时),因此完全避免了零填充操作。 -
是的,和乔纳森说的一样。使用
calloc,但也使用适当的类型size_t而不是unsigned int。这将使程序更具可移植性。您也不需要在 C 中从malloc转换返回值。如果您的第二个 malloc 失败,您调用free_database()并使用未初始化的结构,这可能会出现问题。
标签: c gdb variable-assignment unsigned-integer