就像标题说的,我现在需要将数组从一个不规则的二维数组中复制到另外一个二维数组中,这两个二维数组都是不规则的,而且结构是不一样的,只是所能容纳元素的总长度相等,这种问题,有什么高效的方法吗?谢谢大家了!
1
InkStone 2020-04-16 10:59:01 +08:00
我觉得最大的问题是,两个数组的结构都不一样,你想怎么复制?
如果只是按内存地址顺序复制,那直接 memcpy 就好了。 |
2
across 2020-04-16 11:03:52 +08:00
不能。
不过一开始就自己 malloc 一块区域,手动控制对象,效率会好点吧。 |
3
jngke931126 2020-04-16 11:11:25 +08:00
很好奇这个的应用场景,能说下不,也许有别的办法呢
|
4
linvon 2020-04-16 11:45:33 +08:00
只能自己操作内存了吧
|
5
Kellerman OP @InkStone 那如果说 我是从 n 段不等长的连续内存,复制到 m 段不等长的内存里,有没有比较方便的方法。(段内存内部是连续的,段与段之间是不连续的!)
|
6
Kellerman OP @across 能具体讲讲吗,我的应用场景是,是从 n 段不等长的连续内存,复制到 m 段不等长的内存里,有没有比较方便的方法。(段内存内部是连续的,段与段之间是不连续的!
|
7
Kellerman OP @jngke931126 我是从 n 段不等长的连续内存,复制到 m 段不等长的内存里,有没有比较方便的方法。(段内存内部是连续的,段与段之间是不连续的! 这是应用场景!
|
9
xpfd 2020-04-16 12:31:01 +08:00
自己写个函数,针对每段数据,单独 memcpy
|
10
Kellerman OP @xpfd 那这样的我要比对每一段源和目的内存的长度,然后分情况讨论,这样就会显的非常复杂,有什么更简单的方法吗?
|
11
linvon 2020-04-16 13:02:39 +08:00
@Kellerman 手动根据长度自行 memcpy 呗,你要是嫌双判断麻烦,就先把 n 段先拿出来存放成线性的 x,再把 x 根据 m 段的长度拆解进去
|
12
zhyl 2020-04-16 13:11:44 +08:00
数组存储空间连续, 直接当成内存空间使用 memcpy 拷贝就行了
|
14
zhyl 2020-04-16 13:15:38 +08:00
结构不一样不影响拷贝, 只影响你怎么去解释这个数组
举个例子: 一个 int 数组拷贝到一个 char 数组中, 两个数组的基本元素结构并不一样, int 占 4 字节(假设), char 占 1 字节, 这个结构只影响你后续怎么使用这个数组, 但是拷贝的话是不看结构的, memcpy 前两个参数为 void* 就应该明白这一点 |
15
InkStone 2020-04-16 13:31:48 +08:00
@Kellerman 没看明白你的意思。
n 段内存复制到 m 段内存,n≠m 的时候怎么做映射? 假设 n 段内存的长度为 n1,n2,n3,n4,n5,m 段内存的长度为 m1,m2,m3,m4,m5,n1 要复制到 m1, n1>m1 怎么办,n1<m1 又怎么填充? 你最好不要描述得那么抽象,直接把你想解决的问题说出来给大家听听。 |
16
zjsxwc 2020-04-16 13:37:33 +08:00
对不起我看不懂题目
|
17
xdtr 2020-04-16 13:39:00 +08:00
根据数组 a 的所有数据长度 malloc 一片内存 m,把数组 a 的所有数据按顺序存放到 m 中,然后根据数组 b 的每一段长度从 m 中取出对应的长度存放到 b 中。
|
18
wutiantong 2020-04-16 13:53:45 +08:00
not a good question
我建议对问题做进一步补充: 既然要问的是有什么“高效的”方法,那不妨贴一段代码来展示作为 baseline 的实现。 |
19
pkookp8 2020-04-16 14:06:59 +08:00 via Android
@InkStone 可能问题中 n 和 m 长度虽然不等,但总长 m 大于等于 n
例如 2 段内存,一段 4 字节一段 20 字节 按序拷贝到 3 段内存,一段 8 字节一段 12 字节一段 4 字节 我觉得没办法吧,就是比较长短。短的部分直接拷贝,拷贝后长的部分减去相应长度,继续下一次拷贝 |
20
oahebky 2020-04-16 15:09:25 +08:00
直接复制很低效吗???
|
21
InkStone 2020-04-16 15:25:46 +08:00
@pkookp8 如果放在一段连续的内存里,直接 memcpy 整个长度就好了。
我觉得你这个需求多半是可以塞进连续内存里的。要解析的时候写个 struct reinterpret_cast 一下就好了。 |
23
augustheart 2020-04-16 15:51:13 +08:00
但是如果是不同的结构,不考虑两个结构体是否用可以用来取巧的区别,for 是你唯一可靠的选择。
而且就算开 for 遍历也并不慢。(当然,你也可以考虑用 duff's device 减少循环的消耗) |
24
augustheart 2020-04-16 15:53:20 +08:00
@augustheart 当然,我并没有考虑能不能写个合用的 duff's device,所以就是个瞎说。
但是无论如何,每一个元素都必须处理到 |
25
name1991 2020-04-16 16:23:32 +08:00
如果段与段之间不连续的话是有点难办的
|
26
zjsxwc 2020-04-16 16:47:52 +08:00
C 没有 Rust 的 Match 语法
楼主的需求只能用 yacc 写个转换代码生产机,自动生成 C 代码 |
28
ExplorerLog 2020-04-16 17:25:37 +08:00
sizeof 第一段 和 memcpy 第一段,指针加第一段 size
sizeof 第二段 和 memcpy 第二段,指针加第二段 size ... 循环操作 写个函数 |
29
zjsxwc 2020-04-16 18:44:11 +08:00 via Android
@name1991 #27 原文:“@zjsxwc 写下思路?”
回复: 就是设计一个你 n 段内存数据到 m 段内存数据对应规则的描述语法 X,然后 yacc 设计一个简单的编译器把用语法 X 写的对应规则编译成相应的 C 语言源代码。 这个 X 语法很简单,比如 (n1, len1),(n2, len2),(n3, len3) -> (m1, len4),(m2, len5) 其中 len1+len2+len3==len4+len5 表示把 n 段内存中 3 段数据复制到 m 段内存中的 2 段。 |
30
zjsxwc 2020-04-16 18:54:49 +08:00 via Android
编译出来的 c 代码就是一堆 memcpy 调用以及维护每个 memcpy 三个参数的代码,挺无脑的。
当然也可以不用 yacc 直接解析也行。 |
31
nightwitch 2020-04-16 18:57:46 +08:00
pod 类型直接 for 循环拷贝就行了,不会比你换着花样 memcpy 慢很多的
|
32
Huelse 2020-04-16 19:02:58 +08:00
既然用了 c 语言,就告别了优雅的写法,自己动手操作指针、内存等,楼上都说了很多了
当然用 c++直接 template 好了,实在不行还可以用 gsl |