修改 std::vector 的基础数据结构不会改变其大小

Modifying underlying data structure of std::vector doesn't change its size

我在 class 桥接 JNI 入口点和新的 C++ 库中使用 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;
}

问题

如果我通过 data() 方法修改 vector,它的长度(通过 size() 获得)将保持为 0。你有什么想法如何让矢量显示尺寸正确吗?我会注意到,这个函数被调用了很多次,所以性能非常重要。

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

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

只是 "Returns pointer to the underlying array serving as element storage. The pointer is such that range [data(); data() + size()) is always a valid range, even if the container is empty." http://en.cppreference.com/w/cpp/container/vector/data

相反,

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

可以改成

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

向量的大小当然不会增加。想想看。

您正在使用 GetByteArrayRegion 将数据直接复制到矢量的底层缓冲区。您希望它的 'size' 成员如何改变。

为了解决这个问题,我会在创建矢量时使用它设置矢量的大小 fill constructor

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

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

现在矢量的大小就是您想要的大小,因此使用 GetByteArrayRegion 将数据直接复制到其中应该没问题。