如何将重复图案复制到内存缓冲区中?

| 我想将重复的字节模式写入内存块。我的想法是编写模式的第一个示例,然后将其复制到缓冲区的其余部分。例如,如果我以此开始:
ptr: 123400000000
之后,我希望它看起来像这样:
ptr: 123412341234
我以为我可以用
memcpy
来写相交的区域,像这样:
memcpy(ptr + 4, ptr, 8);
该标准未指定复制将以什么顺序进行,因此,如果某些实现使它以相反的顺序进行复制,则可以给出不同的结果:
ptr: 123412340000
甚至合并结果。 有什么解决方法可以让我仍然使用
memcpy
,还是必须实现自己的for循环?请注意,我不能使用
memmove
,因为它恰好可以避免。它使ptr为
123412340000
,而我要为
123412341234
。 我为Mac / iPhone(clang编译器)编程,但是一般的回答也可以。     
已邀请:
        没有标准功能可以在存储范围内重复字节模式。您可以使用
memset_pattern*
函数系​​列来获取固定大小的图案;如果您需要更改尺寸,则必须自己滚动。
// fills the 12 first bytes at `ptr` with the 4 first bytes of `ptr`
memset_pattern4(ptr, ptr, 12);
请注意,
memset_pattern4
memset_pattern8
memset_pattern16
仅在Mac OS / iOS上存在,因此请勿将它们用于跨平台开发。 否则,滚动(跨平台)函数进行逐字节复制非常简单。
void byte_copy(void* into, void* from, size_t size)
{
    for (size_t i = 0; i < size; i++)
        into[i] = from[i];
}
    
        这是kernel.org所说的:   memcpy()函数复制n个字节   从存储区src到存储区   目的地内存区域不得   交叠。如果memmove(3)   内存区域确实重叠。 MSDN说的是:   如果源和目标重叠,   memcpy的行为是不确定的。   使用记忆处理重叠   地区。     
        所有平台的C ++答案是std :: fill_n(destination,elementRepeats,elementValue)。 对于您的要求:
short val = 0x1234;
std::fill_n(ptr, 3, val); 
这将适用于任何类型的val;字符,短裤,整数,int64_t等     
        旧答案 要16英镑。详细描述:   memmove()函数应将s2指向的对象中的n个字节复制到s1指向的对象中。好像是先复制s2指向的对象的n个字节,然后将其复制到不与s1和s2指向的对象重叠的n字节的临时数组中,然后再复制该临时数组的n个字节。 s1指向的对象。 在
memcpy()
页面上:   如果在重叠的对象之间进行复制,则行为是不确定的。 无论如何,您都必须使用
memmove()
。这是因为使用
memcpy()
的结果在任何方面都不可靠。 与实际问题相关的位 您要的是
memcpy(ptr + 4, ptr, 8);
,表示从
ptr
复制8个字节并将其放在at22ѭ处。
ptr
是123400000000,前8个字节是1234000,因此它是这样做的:
Original : 123400000000
Writes   :     12340000
Result   : 123412340000
您需要致电:
memcpy(ptr+4, ptr, 4);
memcpy(ptr+8, ptr, 4);
实现您的追求。或实施等效方法。应该这样做,但是未经测试,等效于memcpy;您将需要添加额外的临时缓冲区或使用两个不重叠的内存区域。
void memexpand(void* result, const void* start, 
               const uint64_t cycle, const uint64_t limit)
{
    uint64_t count = 0;
    uint8_t* source = start;
    uint8_t* dest   = result;

    while ( count < limit )
    {
        *dest = *source;
        dest++;
        count++;

        if ( count % cycle == 0 )
        {
            source = start;
        }
        else
        {
            source++;
        }
    }
}
    
        您可以执行以下操作:先复制一次,然后将所有内容都“ 2”复制到以下字节中,然后重复该操作,最好在代码中理解:
void block_memset(void *destination, const void *source, size_t source_size, size_t repeats) {
    memcpy(destination,source,source_size);
    for (size_t i = 1; i < repeats; i += i)
        memcpy(destination + i,destination,source_size * (min(i,repeats - i)));
}
我进行基准测试;对于大量的ѭ30as,它的速度与常规ѭ29as一样快,而ѭ31dynamic则非常动态,而且性能损失也不多。     
        为什么不只是分配一个8字节的缓冲区,将其移到那里,然后再将其移回所需的位置? (如@cnicutar所说,memcpy不应有重叠的地址空间。)     

要回复问题请先登录注册