我需要将重复模式写入内存(例如0x11223344
),以便整个内存看起来像(以十六进制表示):
1122334411223344112233441122334411223344112233441122334411223344...
我不知道该怎么做,memset()
因为它只需要一个字节,而不是 4 个字节。
有任何想法吗?
我需要将重复模式写入内存(例如0x11223344
),以便整个内存看起来像(以十六进制表示):
1122334411223344112233441122334411223344112233441122334411223344...
我不知道该怎么做,memset()
因为它只需要一个字节,而不是 4 个字节。
有任何想法吗?
在 OS X 上,memset_pattern4( )
用于此;我希望其他平台也有类似的 API。
我不知道一个简单的便携式解决方案,除了用循环填充缓冲区(这非常简单)。
递归地复制内存,使用您已经填充的区域作为每次迭代 O(log(N)) 的模板:
int fillLen = ...;
int blockSize = 4; // Size of your pattern
memmove(dest, srcPattern, blockSize);
char * start = dest;
char * current = dest + blockSize;
char * end = start + fillLen;
while(current + blockSize < end) {
memmove(current, start, blockSize);
current += blockSize;
blockSize *= 2;
}
// fill the rest
memmove(current, start, (int)end-current);
我对 O(log(N)) 的意思是,运行时将比手动填充内存要快得多,因为memmove()
通常使用特殊的、手动优化的汇编程序循环,速度非常快。
一种有效的方法是将指针转换为所需大小(以字节为单位)的指针(例如uint32_t
,对于 4 个字节)并用整数填充。虽然有点丑。
char buf[256] = { 0, };
uint32_t * p = (uint32_t *) buf, i;
for (i = 0; i < sizeof(buf) / sizeof(* p); i++) {
p[i] = 0x11223344;
}
未测试!
如果您的模式适合 a wchar_t
,您可以wmemset()
像使用memset()
.
您可以在某处设置序列,然后将其复制memcpy()
到您需要的位置。
好吧,这样做的正常方法是手动设置前四个字节,然后memcpy(ptr+4, ptr, len -4)
这会将前四个字节复制到后四个字节中,然后将后四个字节复制到第三个字节中,依此类推。
请注意,这“通常”有效,但不能保证,具体取决于您的 CPU 架构和您的 C 运行时库。
标准 C 库没有这样的功能。但是 memset 通常被实现为展开循环以最小化分支和条件检查:
static INLINE void memset4(uint32_t *RESTRICT p, uint32_t val, int len) {
uint32_t *end = p + (len&~0x1f); //round down to nearest multiple of 32
while (p != end) { //copy 32 times
p[ 0] = val;
p[ 1] = val;
p[ 2] = val;
p[ 3] = val;
p[ 4] = val;
p[ 5] = val;
p[ 6] = val;
p[ 7] = val;
p[ 8] = val;
p[ 9] = val;
p[10] = val;
p[11] = val;
p[12] = val;
p[13] = val;
p[14] = val;
p[15] = val;
p[16] = val;
p[17] = val;
p[18] = val;
p[19] = val;
p[20] = val;
p[21] = val;
p[22] = val;
p[23] = val;
p[24] = val;
p[25] = val;
p[26] = val;
p[27] = val;
p[28] = val;
p[29] = val;
p[30] = val;
p[31] = val;
p += 32;
}
end += len&0x1f; //remained
while (p != end) *p++ = val; //copy remaining bytes
}
好的编译器可能会使用一些特定于 CPU 的指令来进一步优化它(例如使用 SSE 128 位存储),但即使没有优化,它也应该与库 memset 一样快,因为这种简单的循环是内存访问受限的。