我正在查看一些C ++代码,我遇到了这个memcpy函数。我理解memcpy的作用,但是他们在源代码中添加了一个int。我试着查找memcpy的源代码,但我似乎无法理解添加实际上对memcpy函数做了什么。
memcpy(Destination, SourceData + intSize, SourceDataSize);
换句话说,我想知道SourceData + intSize正在做什么。 (我试图将其转换为java。)
编辑:
所以这是我尝试使用for循环在java中执行memcpy函数...
for(int i = 0 ; i < SourceDataSize ; i ++ ) {
Destination[i] = SourceData[i + 0x100];
}
答案 0 :(得分:10)
与以下内容相同:
memcpy(&Destination[0], &SourceData[intSize], SourceDataSize);
答案 1 :(得分:1)
添加将更改用于内存副本源的地址。
地址更改的数量取决于SourceData的类型。
(见http://www.learncpp.com/cpp-tutorial/68-pointers-arrays-and-pointer-arithmetic/)
它可能正在尝试从偏移量intSize开始复制数组SourceData的一部分,并且长度为SourceDataSize / sizeof(* SourceData)。
修改
因此,例如,如果数组的大小为4个字节的整数,则等效的Java代码如下所示:
for(int i = 0 ; i < SourceDataSize/4 ; i ++ ) {
Destination[i] = SourceData[i + intSize];
}
答案 2 :(得分:1)
这是基本的指针算法。 SourceData指向某种数据类型,向它添加n会增加n * sizeof(* SourceData)所指向的地址。
例如,如果SourceData定义为:
uint32_t *SourceData;
和
sizeof(uint32_t) == 4
然后向SourceData添加2会将其保存的地址增加8。
另外,如果将SourceData定义为数组,则向其中添加n有时与访问数组的第n个元素相同。很容易看到n == 0;当n == 1时,很容易看到你将在数组开始后访问sizeof(* SourceData)字节的内存地址。
答案 3 :(得分:1)
SourceData + intSize在SourceData的开头跳过intSize * sizeof(源数据类型)字节。也许SourceDataSize存储在那里或类似的东西。
答案 4 :(得分:0)
Java中与memcpy
最接近的等价物是System.arraycopy
,因为Java实际上没有相同意义上的指针。
答案 5 :(得分:0)
关于在Java中执行此操作:
你的循环
for(int i = 0 ; i < SourceDataSize ; i ++ ) {
Destination[i] = SourceData[i + 0x100];
}
将始终开始将0x100
元素中的数据复制到SourceData中;这可能不是理想的行为。 (例如,当i=0
,Destination[0] = SourceData[0 + 0x100];
等等。)如果您从未想要复制SourceData[0]..SourceData[0xFF]
,那么这就是您想要的,但请注意,硬编码可以防止它被复制memcpy的替代品。
原始代码中指定intSize
值的原因可能是因为第一个intSize
元素不是“实际”数据的一部分,并且这些字节以某种方式用于簿记(如记录缓冲区的总大小)。 memcpy
本身并没有“看到”偏移量;它只知道它开始的指针。 SourceData + intSize
创建一个指针,指出intSize
个字节超过SourceData
。
但是,更重要的是,你正在做的事情可能是非常慢。 memcpy
是非常重度优化的函数,它映射到大多数体系结构上经过精心调整的程序集,并用简单的每字节循环迭代替换它将极大地影响代码的性能特征。虽然你正在尝试理解memcpy和指针是如何工作的是合适的,但请注意,如果你试图将现有代码移植到Java以供实际使用,你可能会想要使用道德上的等价物Java函数,如java.util.Arrays.copyOf
。