【发布时间】:2013-12-24 13:32:35
【问题描述】:
好的,首先描述一下我的问题。我有一个示例程序,只有一个文件。唯一包含的头文件是标准库的一部分。为了训练和测试,我编写了自己的 malloc 包装器,它会自动将 0 写入整个存储块。在我的上网本(Debian + Gnome 桌面,像这样的原始 gcc 调用:gcc memstest.c -o memstest)它运行没有问题。即使由于基准测试,我删除了对存储的每个部分的整个迭代检查,但对任何其他数据然后 0 的检查都是成功的。在 Windows 上尝试使用 Code::Blocks 作为 IDE 并配置 GNU gcc 编译器时,它告诉我在分配的存储中存在数据(大多数时候值为 -60)。正如所见,我主要只使用无符号值,因此在将其写入数据块时,该值不可能是我的失败。我猜是memcpy 函数,因为它是唯一触及这个数据块的例程。如果我记错了,我会更改主题标题。
这是我的示例程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iso646.h>
#include <time.h>
void *Smalloc_dyn( unsigned int n_bytes );
int main( void )
{
time_t start_t, end_t;
double difference;
unsigned int index = 0;
start_t = time( NULL );
for( index = 0; index < 10000000; index++ )
{
char *test = Smalloc_dyn( 65536 );
if( *test != 0 )
{
printf( "Found data without 0 overwriting...\n" );
return 0;
}
free( test );
}
end_t = time( NULL );
difference = difftime( end_t, start_t );
printf( "Smalloc_dyn took %.1fs\n", difference );
start_t = time( NULL );
for( index = 0; index < 10000000; index++ )
{
char *test = calloc( ( 65535 / sizeof( (long) 0 ) ), ( 65536 / ( 65535 / sizeof( (long) 0 ) ) ) );
if( *test != 0 )
{
printf( "Found data without 0 overwrting...(2)\n" );
return 0;
}
free( test );
}
end_t = time( NULL );
difference = difftime( end_t, start_t );
printf( "calloc took %.1fs\n", difference );
return 0;
}
void *Smalloc_dyn( unsigned int n_bytes )
{
/*
This fusion of malloc and a modified memset
is way faster than calling malloc() and
after that memset( *dst, 0, len(dst) ).
We are defining 0 as a long and will
therefore copy ( for example ) 8 Bytes
instead of a per-byte copying.
With a memory need of 1024, we only
have 128 steps instead of 1024.
*/
if( 0 == n_bytes )
{
return NULL;
}
long unsigned int chr = 0;
unsigned int steps = sizeof( chr ) / n_bytes;
unsigned int asteps = n_bytes % sizeof( chr );
unsigned int index = 0;
char *mem_ptr = malloc( n_bytes );
if( NULL == mem_ptr )
{
return mem_ptr;
}
char *write_ptr = mem_ptr;
for( index = 0; index < steps; index++ )
{
memcpy( write_ptr, &chr, sizeof( chr ) );
write_ptr = write_ptr + sizeof( chr );
}
for( index = 0; index < asteps; index++ )
{
memcpy( write_ptr, &chr, 1 );
write_ptr = write_ptr + 1;
}
return mem_ptr;
}
编辑:更正的代码
【问题讨论】:
-
所以你意识到 sizeof(chr)/n_bytes 将是零,对吧?整数 4/65536 为 0。asteps 也为 0,因为 65536 % 4 为 0。所以你根本不会调用 memset。也许这就是它“更快”的原因:)
-
这又是“由于树木太多而看不到森林”的例子之一。我正在寻找某种价值错误。好的,又是一个很好的教训,重新阅读自己的代码超过 2 次 :)
标签: c linux windows memory gcc