繁体   English   中英

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

[英]C memcpy behaves differently on Linux and Windows

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

编辑:更正的代码

为什么steps的值被评估为

unsigned int steps = sizeof( chr ) / n_bytes;

而不是

unsigned int steps = n_bytes / sizeof( chr );

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM