修改std :: vector的底层数据结构并不会改变它的大小

时间:2015-10-23 10:19:49

标签: c++ c++11 vector java-native-interface

我在使用新C ++库桥接JNI入口点的类中使用std::vector

由于有很多涉及jbyteArray的JNI调用,我编写了简单的转换函数:

std::vector<uint8_t> Jni::Types::vectorForJarray(jbyteArray a) {
    auto env = Jni::getEnv();
    auto len = env->GetArrayLength(a);
    std::vector<uint8_t> result;
    result.reserve(static_cast<unsigned int>(len));
    env->GetByteArrayRegion (a, 0, len, reinterpret_cast<jbyte*>(result.data()));
    return result;
}

jbyteArray Jni::Types::JarrayForVector(std::vector<uint8_t> v) {
    auto env = Jni::getEnv();
    auto array = env->NewByteArray(v.size());
    if (env->GetArrayLength(array) != v.size()) {
        env->DeleteLocalRef(array);
        array = env->NewByteArray(v.size());
    }
    void* temp = env->GetPrimitiveArrayCritical(array, 0);
    memcpy(temp, v.data(), v.size());
    env->ReleasePrimitiveArrayCritical(array, temp, 0);
    return array;
}

问题

如果我通过vector方法修改data(),其长度(通过size()获得)将保持为0.您是否有任何想法如何使向量显示正确的大小?我会注意到,这个函数被称为很多次,因此性能非常重要。

2 个答案:

答案 0 :(得分:2)

当然,矢量的大小不会增加。想一想。

您正在使用GetByteArrayRegion将数据直接复制到矢量的底层缓冲区。你怎么期望它的'大小'成员改变。

要解决此问题,我会设置矢量的大小,因为我使用fill constructor

创建它
std::vector<uint8_t> result(static_cast<unsigned int>(len), 0);

这将创建向量并用len个元素填充它,每个元素都是第二个参数的副本,在本例中为0。

现在,矢量的大小是你想要的,所以使用GetByteArrayRegion将数据直接复制到它中应该没问题。

答案 1 :(得分:1)

memcpy(temp, v.data(), v.size());

此行不会更改std :: vector的size属性。

只是 &#34;返回指向用作元素存储的基础数组的指针。指针是范围[data(); data()+ size())始终是有效范围,即使容器为空。&#34; http://en.cppreference.com/w/cpp/container/vector/data

相反,

result.reserve(static_cast<unsigned int>(len));

可以更改为

result.resize(static_cast<unsigned int>(len));