C++对vector bool::data()用memset报错

本文探讨了C++中vector<bool>的特殊性及其替代方案,通过自定义bool_vec结构,对比了其与vector<bool>及vector<int>在初始化和内存设置操作上的性能差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本来想尝试用 menset 来代替 forvector<bool> 赋初值,看会不会提速,报错。出错例程:

#include <cstdio>
#include <vector>
using namespace std;

int main()
{
	vector<bool> vb;
	vb.reserve(128);
	printf("vector<bool> ptr: %p\n", vb.data());  // ERROR
	return 0;
}

报错:

err.cpp: In function 'int main()':
err.cpp:9:44: error: invalid use of void expression
  printf("vector<bool> ptr: %p\n", vb.data());

才知道 vector<bool> 是比较特殊的,用位存,而不是 bool 数组,不能照套 vector<int> 的 API。因为 bitset 不能运行时指定长度,自己写一个 bitset,顺便测试一下性能,跟 vector<bool> 对比:

#include <bits/stdc++.h>
using namespace std;
const int N = 20000000;


struct bool_vec
{
	typedef unsigned int dtype;
	const int UNIT = sizeof(dtype),
			  B = 8 * UNIT,
			  MASK = (1LL << B) - 1;
	vector<dtype> vec;
	bool_vec(int size)
	{
		vec.reserve((size + B - 1) / B);
		// printf("B: %d, MASK: %x\n", B, MASK);
		// printf("wanted size: %d, capacity: %d\n", (size + B - 1) / B, vec.capacity());
	}
	inline int operator [] (int pos)
	{
		// return (vec[pos / B] >> (pos % B)) & 1;
		return (vec[pos / B] >> (pos & MASK)) & 1;
	}
	void set(int pos = -1)
	{
		if (pos >= 0)
		{
			// vec[pos / B] |= 1 << (pos % B);
			vec[pos / B] |= 1 << (pos & MASK);
		}
		else
			memset(vec.data(), 0xff, vec.capacity() * UNIT);
	}
	void reset(int pos = -1)
	{
		if (pos >= 0)
		{
			// vec[pos / B] &= ~(1 << (pos % B));
			vec[pos / B] &= ~(1 << (pos & MASK));
		}
		else
			memset(vec.data(), 0, vec.capacity() * UNIT);
	}
};


int main()
{
	vector<int> vi;
	vector<bool> vb;
	bool_vec b_vec(N);
	double cost;

	vi.reserve(N);
	vb.reserve(N);

	// for int
	clock_t start = clock();
	for (int *b = vi.data(), *e = vi.data() + N; b < e; )
		*b++ = -1;
	cost = (double)(clock() - start) / CLOCKS_PER_SEC;
	printf("for vector<int>: %f\n", cost);

	// memset int
	start = clock();
	memset(vi.data(), -1, N * sizeof(int));
	cost = (double)(clock() - start) / CLOCKS_PER_SEC;
	printf("memset vector<int>::data: %f\n", cost);

	// for bool
	start = clock();
	for (int i = 0; i < N; )
		vb[i++] = false;
	cost = (double)(clock() - start) / CLOCKS_PER_SEC;
	printf("for vector<bool>: %f\n", cost);
	
	// for bool_vec
	start = clock();
	for (int i = 0; i < N; )
		b_vec.set(i++); // set 1
	cost = (double)(clock() - start) / CLOCKS_PER_SEC;
	printf("for bool_vec: %f\n", cost);

	puts("--- test 1 ---");
	for (int i = 0; i < 200; i += 37)
		printf("b_vec[%d]: %d\n", i, b_vec[i]);

	// memset int
	start = clock();
	b_vec.reset();  // set 0
	// for (int i = 0; i < N; )
		// b_vec.reset(i++); // set 0
	printf("memset bool_vec: %f\n", cost);

	puts("--- test 0 ---");
	for (int i = 0; i < 200; i += 37)
		printf("b_vec[%d]: %d\n", i, b_vec[i]);

	return 0;
}

结果:

for vector<int>: 0.093191
memset vector<int>::data: 0.007326
for vector<bool>: 0.424405
for bool_vec: 0.136087
--- test 1 ---
b_vec[0]: 1
b_vec[37]: 1
b_vec[74]: 1
b_vec[111]: 1
b_vec[148]: 1
b_vec[185]: 1
memset bool_vec: 0.136087
--- test 0 ---
b_vec[0]: 0
b_vec[37]: 0
b_vec[74]: 0
b_vec[111]: 0
b_vec[148]: 0
b_vec[185]: 0

似乎比 vector<bool> 要快些少,然而比 memset vector<int> 要慢?这是为什么?函数也是调的 memset 啊

References

  1. What happens when you call data() on a std::vector?
  2. c++中为什么不提倡使用vector?
  3. Fast std::vector Reset
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值