矢量上的 memset 使其大小为 0

memset on vector is making its size 0

我试图使用 memset 在不改变其大小的情况下清除矢量中的所有数据。但是经过memset运算后vector的大小变为0。具体代码如下:

std::vector<T> buckets[2];
MAX_BUCKET_SIZE=16;

构造函数:

buckets[0].resize(MAX_BUCKET_SIZE);
std::cout << "Actual size0 " << buckets[0].size() << std::endl;
buckets[1].resize(MAX_BUCKET_SIZE);
std::cout << "Actual size1 " << buckets[1].size() << std::endl;

在函数中:

std::cout << "Actual size2 0 " << buckets[0].size() << std::endl;
std::cout << "Actual size2 1 " << buckets[1].size() << std::endl;
...
...
while (...){
    delete_data(current_bucket);

    std::cout << "current bucket ** " << current_bucket << std::endl;
    std::cout << "Actual size3 0 " << buckets[0].size() << std::endl;
    std::cout << "Actual size3 1 " << buckets[1].size() << std::endl;
}

delete_data 函数:

memset(&buckets[bucket_id], 0, sizeof(buckets[bucket_id]));

输出:

Actual size0 16
Actual size1 16
Actual size2 0 16
Actual size2 1 16
current bucket ** 1
Actual size3 0 16
Actual size3 1 0
current bucket ** 0
Actual size3 0 0
Actual size3 1 0

不要那样做。破坏 class 实例的自动存储可能会导致未定义的行为。例如,我想象向量元素的任何析构函数都不会被调用。

调用 resize 为零将实现基本相同的结果。或者只是将 buckets 重新分配给 std::vector<T>.

的新实例

更不用说非 POD 上的 memset 未定义的行为 ,看起来你只是 "succeeded" memset-ing 向量的内部数据 - 可以是指向实现的指针或指向基础数组的 start/end 的指针。您没有修改元素,实际上您丢失了它们(并泄漏了内存)。

您很可能想对底层数组进行操作(不过,T 必须是 POD):

memset(&buckets[bucket_id].front(), 0, buckets[bucked_id].size() * sizeof(T));

但是在 C++ 中没有人这样做,因为有 STL 解决方案,比如 std::fill:

std::fill(buckets[bucket_id].begin, buckets[bucket_id].end(), T{});

这将用默认构造的 T(可以是非 POD)的副本填充数组。

另请注意,sizeof(buckets[bucket_id]) 为您提供了完全没有意义的数字。

I was trying to clear all data in a vector without changing its size using memset.

不行,因为它不关注被填充的区域。在使用指针实现 std::vector 的情况下,您应用它的方式也会造成内存泄漏,因为指针被清零了。

改用std::fill

std::fill(buckets[0].begin(), buckets[0].end(), 0);

您正在 class 上执行 memset,这充其量是未定义的行为。你怎么知道将对象使用的内存设置为零对对象有意义?例如,如果向量存储指向它包含的项目的指针,那么您将该指针设置为空,从而导致内存泄漏。

运气好会撞车,运气不好就不会。