我需要在FFI中传递一个元素的Vec.通过实验,我发现了一些有趣的观点.我开始给FFI全部3:ptr,len和容量,以便我可以重建Vec以便以后销毁它:
let ptr = vec.as_mut_ptr();
let len = vec.len();
let cap = vec.capacity();
mem::forget(vec);
extern_fn(ptr,len,cap);

// ...

pub unsafe extern "C" fn free(ptr: *mut u8,len: usize,cap: usize) {
    let _ = Vec::from_raw_parts(ptr,cap);
}

我想摆脱容量,因为它对我的前端没用;它只是为了让我可以重建我的矢量来释放记忆.

Vec :: shrink_to_fit()很有吸引力,因为它似乎消除了处理容量的需要.不幸的是,它上面的文档并不保证它会使len ==容量,因此我假设在from_raw_parts()期间可能会触发Undefined Behavior.

into_Boxed_slice()似乎有一个保证,它将从docs获得len ==容量,所以我接下来使用它.如果我错了,请纠正我.问题是它似乎不能保证不重新分配.这是一个简单的程序:

fn main() {
    let mut v = Vec::with_capacity(1000);
    v.push(100u8);
    v.push(110);
    let ptr_1 = v.as_mut_ptr();
    let mut Boxed_slice = v.into_Boxed_slice();
    let ptr_2 = Boxed_slice.as_mut_ptr();
    let ptr_3 = Box::into_raw(Boxed_slice);
    println!("{:?}. {:?}. {:?}",ptr_1,ptr_2,ptr_3);
}

In the playground,它打印:

rustc 1.14.0 (e8a012324 2016-12-16)
0x7fdc9841b000. 0x7fdc98414018. 0x7fdc98414018

如果必须找到新的内存而不是在不造成副本的情况下脱掉额外的容量,这就不好了.

有没有其他方法可以将我的矢量传递到FFI(到C)而不传递容量?似乎into_Boxed_slice()是我需要的,但为什么它涉及重新分配和复制数据?

解决方法

原因相对简单.

现代内存分配器将在“大小”平板中分离分配,其中每个平板负责处理给定范围的大小.例如:

> 8字节slab:1到8个字节的任何内容
> 16字节slab:从9到16字节的任何内容
> 24字节slab:从17到24字节的任何内容
> ……

当你分配内存时,你要求一个给定的大小,分配器找到正确的slab,从中获取一个块,然后返回你的指针.

当你释放内存时…你怎么期望分配器找到合适的平板?有两种解决方案:

>分配器有办法搜索包含你的内存范围的板,不知何故,它涉及通过板块的线性搜索或某种全局查找表或……
>告诉分配器分配块的大小是多少

这里显而易见的是,C接口(free,realloc)相当低于标准,因此Rust希望使用更有效的接口,即onus在调用者上的接口.

所以,你有两个选择:

>通过容量
>确保长度和容量相等

如您所知,(2)可能需要新的分配,这是非常不受欢迎的. (1)可以通过全程传递容量来实现,也可以在某个时候存储容量,然后在需要时检索它.

而已.你必须评估你的权衡.

vector – 在没有重新分配的情况下将Vec转换为FFI的正确方法是什么?的更多相关文章

  1. 在编译时编译Xcode中的C类错误:stl vector

    我有一个C类,用gcc和可视化工作室中的寡妇在linux上编译.boid.h:并在boid.cpp中:但是,当我在Xcode中编译此代码时,我收到以下错误:有任何想法吗?我以为你可以使用C/C++代码并在Xcode中编译没有问题?.m文件被视为具有Objective-C扩展名的.c文件..mm文件被视为具有Objective-C扩展名的.cpp文件,那么它被称为Objective-C只需将.m文件重命名为.mm,右键单击或按住Ctrl键并在Xcode中的文件中选择重命名.

  2. swift2 运算符函数

    运算符函数前置或后置运算符函数前标注prefix或postfix组合赋值表达式比较运算符自定义运算符在自定义运算符中还可以设定自定义运算符的优先级和结合性,来处理更复杂的任务。

  3. Swift高级运算符(Advanced Operators)

    按位运算符~1变0,0变1。$全1得1,其他为0|有1得1,其他为0^相异为1,相同为0整体右移,左边填0。算子函数上面讲解的都是简单的运算符,下面的是为对象添加运算符,使之可计算。符号在中间前缀和后缀前缀关键字prefix后缀关键字postfix复合赋值运算符这里用+=举例。

  4. android – 在onRestoreInstanceState中发生ClassCastException

    ClassCastException随机发生以恢复onRestoreInstanceState()中的Vector.通常恢复向量很好,但有时会发生异常.我认为它发生在活动进入后台并被破坏但我不确定.有任何想法吗?谢谢.添加:我忘了附上异常日志.那是解决方法我使用下一个代码来恢复Vector:它会阻止java.lang.classCastException并保存元素顺序.要恢复Stack,您可以使用

  5. android – Build在debug中运行,在release中失败 – ZipException重复条目

    我正在将应用程序从2.3升级到Nougat(SDK25).当我添加com.android.support:appcompat-v7:25.0.0以支持ActivityCompat.requestPermissions时.当我在调试模式下运行它时,应用程序运行没有问题,但使用./gradlewassembleDebug运行会导致以下错误:当我在调试模式下运行时,应用程序构建没有问题,但是,当我尝试构

  6. 使用Android NDK和std :: vector修复Eclipse错误

    我正在使用eclipse开发一个也使用ndk的Android应用程序.我在我的应用程序中载入,我已经完成了必要的操作,让它们包含在内APP_STL:=stlport_static在我的Application.mk一切工作正常编译和运行,但是当我使用向量时,Eclipse会给我错误例如创建一个错误.如果我删除错误并继续进行编译并运行正常.我已经添加${NDKROOT}/sources/cxx-stl/gnu-libstdc/include在我的项目配置下,CGeneral–>路径和符号–>包括它解析#inc

  7. 是否可以将对象向量中的函数绑定到std::函数,或者如何以这种方式从对象向量中访问函数

    “主”配置成员之一是辅助配置对象的向量,用于覆盖主配置选项。我可以将“主”配置get方法绑定到函数,我将这些函数添加到向量中,并在测试中使用它们来获取这些参数我希望类似地绑定二级配置中的get方法,特别是向量中的最后一个方法,但我不确定如何做到这一点,或者这是否可能。我已经尝试了一些对我来说有意义的调整,但我开始怀疑这对于我正在创建的卷积量是否是一个好主意。

  8. C++在读取带有向量的结构时遇到问题<字符串>从二进制文件

    我正在做OOP的最后一个项目,其中一部分是制作一些数据库,我在这方面遇到了麻烦。每次创建Alquilerx时,都需要转到数据库的vector,然后将其存储在二进制文件中。问题是我可能管理的大小不对,因为一旦我添加了几个Alquiler,数组就会被垃圾填满,总是输出随机字符。这是代码,我试图尽可能地压缩它,只留下相关部分。如果有人想看一看,我会非常感谢。

  9. 将卡片插入一副卡片

    所以我有这个程序,我想实现一个insertvoid函数。基本上我想把一张卡片插入卡片组。输出应该是一副牌和洗牌版本,然后插入一张牌并再次排序。我怎样才能做到这一点?甲板.cpp甲板.h主.cpp现在我只编写了函数本身。

  10. ubuntu OpenMP parallel for

    要改成普通的int遍历。

随机推荐

  1. 基于EJB技术的商务预订系统的开发

    用EJB结构开发的应用程序是可伸缩的、事务型的、多用户安全的。总的来说,EJB是一个组件事务监控的标准服务器端的组件模型。基于EJB技术的系统结构模型EJB结构是一个服务端组件结构,是一个层次性结构,其结构模型如图1所示。图2:商务预订系统的构架EntityBean是为了现实世界的对象建造的模型,这些对象通常是数据库的一些持久记录。

  2. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  5. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  6. Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等

  7. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  8. 面试突击之跨域问题的解决方案详解

    跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。那怎么解决这个问题呢?接下来我们一起来看

  9. Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. mybatis-plus雪花算法增强idworker的实现

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,进一步增强实现生成分布式唯一ID,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部