c - memcpy() 和 memset() 的奇怪行为
问题描述
我发现 MSVC2017 中的 memcpy() 和 memset() 函数有些奇怪,我无法解释。具体来说,“目标”不是按单个字节索引,而是按结构的整个大小(“大小”参数)索引。
所以我有一个结构:
typedef struct _S
{
int x;
int y;
} S;
代码如下:
S* array = (S*)malloc(sizeof(S) * 10); /* Ok. Allocates enough space for 10 structures. */
S s; /* some new structure instance */
/* !!! here is the problem.
* sizeof(S) will return 8
* 8*1 = 8
* now the starting address will be: array+8
* so I'm expecting my structure 's' to be copied to
* the second ''element'' of 'array' (index 1)
* BUT in reality it will be copied to the 7th index!
*/
memcpy(array + (sizeof(S) * 1), &s, sizeof(S));
/* After some tests I found out how to access 'properly' the
* 'array':
*/
memcpy(array + 1, &s, sizeof(S); /* this will leave the first struct
in the 'array' unchanged and copy 's's contents to the second
element */
memset() 也一样。到目前为止,我认为应该手动完成索引,同时提供复制对象的大小,但不是吗?
memcpy(destination + (size * offset), source + (size * offset), size)
难道我做错了什么?
解决方案
memcpy
并且memset
不是本案的罪魁祸首。您的问题来自对指针算术的误解。
当您将数字添加到指针时,指针会前进那么多元素,而不是那么多字节。因此,如果sizeof(S) == 8
,则指向 an 的指针S
在加 1 时前移 8 个字节,在加 2 时前移 16 个字节,依此类推。关键是您可以从图片中抽象出字节(以及元素的大小)。
因此,如果您分配了一个包含三个元素的数组S
,您的内存可能会像这样布置:
- 3×
S
- 6×
int
- 18 x
char
(字节)
您希望能够忽略字节,并且只通过 访问x
andy
字段S
,以便留下S
-size 的内存块。
|0 |1 |2 | array : S *
|x y |x y |x y | S[N]->x, S[N]->y : int *
|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| individual bytes : char *
推荐阅读
- azure - Microsoft.ApplicationInsights.DependencyCollector 是否适用于 Azure Functions?
- css - 当用户滚动到它时,如何让 div 粘在屏幕底部?
- python - 如何在 python 中执行多线程 selenium 程序?
- c - 使用 memset 初始化整数数组
- wordpress - 不同文件夹中多个 WordPress 安装的 htaccess 问题
- amazon-web-services - 无法让 HTTPS 与 S3 上的静态托管站点一起使用
- javascript - Webpack 导入代码拆分渲染
- xamarin.forms - Xamarin 在其中键入文本时在列表视图弹出窗口中形成带有建议项的条目
- qt - 在 Qt 对话框中让文本像终端一样滚动?
- r - dplyr::filter() 用于数据库