C memcpy在Linux和Windows上的行为有所不同

时间:2013-12-07 02:19:55

标签: c linux windows memory gcc

好的,首先是对我的问题的描述。我有一个示例程序,只有一个文件。唯一包含的标题是标准库的一部分。为了进行培训和测试,我编写了自己的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;
}

编辑:更正代码

1 个答案:

答案 0 :(得分:2)

为什么steps的值被评估为

unsigned int steps = sizeof( chr ) / n_bytes;

而不是

unsigned int steps = n_bytes / sizeof( chr );

这看起来像是问题的潜在来源,因为由于此错误,大多数已分配的块将保持未初始化状态。在“大多数”情况下,steps最终会为零(例如nbytes65536的测试用例)。未初始化的数据可以在平台之间轻松“表现”不同。