好的,首先是对我的问题的描述。我有一个示例程序,只有一个文件。唯一包含的标题是标准库的一部分。为了进行培训和测试,我编写了自己的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;
}
编辑:更正代码
答案 0 :(得分:2)
为什么steps
的值被评估为
unsigned int steps = sizeof( chr ) / n_bytes;
而不是
unsigned int steps = n_bytes / sizeof( chr );
这看起来像是问题的潜在来源,因为由于此错误,大多数已分配的块将保持未初始化状态。在“大多数”情况下,steps
最终会为零(例如nbytes
为65536
的测试用例)。未初始化的数据可以在平台之间轻松“表现”不同。