使用C ++ 11,我喜欢创建一个布尔数组并立即清除它
bool *mymap = new bool[n];
n是可变的。
现在,这是否已经清除了阵列占用的内存?如果没有,是否有更好的方法来清除数组,而不是在所有元素上使用循环,将每个元素分别设置为false?
我考虑使用std:memset(),但这需要我知道数组的大小。现在,初学者可能会说:容易,大小是n * sizeof(布尔)。但我不买。编译器可能决定以不同方式打包它们,甚至将它们打包为位,不是吗?
那么,有没有办法更清晰地告诉数组的大小?我想可能有一个std:arraysize()函数,它只返回内存中已分配数组的空间。毕竟,必须以某种方式在运行时维护该信息,否则删除调用将不知道要释放多少,对吧?
答案 0 :(得分:10)
具体问题的答案是否定的,您无法确定mymap
指向的数组的长度。该语言根本没有提供相应的机制。
但是如果你想要做的就是确保数组的所有元素都设置为false
,那么你所要做的就是将值初始化:
bool* mymap = new bool[n]();
// ^^
不幸的是,这仅适用于内置类型的零值。没有相同的方法可以将所有值设置为true
。
答案 1 :(得分:6)
你不能以标准的方式做到这一点。但是,不同的编译器支持不同的黑客攻击,例如:
#if defined(_MSC_VER) || ( defined(__GNUC__) && defined(_WIN32) )
// a dirty MSVC and MinGW hack
size_t Size = _msize( mymap );
#elif defined(__GNUC__)
// a dirty glibc hack
size_t Size = malloc_usable_size( mymap );
#else
#error Implement for any other compiler
#endif
但这些都是真正的黑客,所以要小心。
顺便说一下,std::vector
可以帮助您在标准范围内解决问题。
答案 2 :(得分:4)
不,你不能,因为它实际上不是一个数组。 mymap
只是指向某些堆内存的正常指针,如果您需要知道大小,您必须自己跟踪它或使用标准容器,例如std::vector
。
哦,如果你想要memset
更通用的变体,请阅读std::fill
。
答案 3 :(得分:4)
不,编译器无法决定打包它们,除非区域大小为n * sizeof(bool)
- 以任何其他方式执行此操作会破坏将{1}}作为单个数组成员的能力(这与mymap[x]
)相同。
在这种情况下,初学者的建议是正确的。
答案 4 :(得分:2)
你可以试试这个:
bool *mymap = new bool[n] ();
但是设置为false
并且您无法使用这种方式设置为true
。
答案 5 :(得分:2)
我们假设编译器决定采用不同的方式打包。
假设1:编译器将一些位一起打包成一个字节。如果你获取数组中单个元素的地址,它的类型为bool。由于编译器不能(通常)推断出你将对该地址做什么(例如将其传递给将其传递给lib的函数,...),因此在一个字节内进行位打包不会真正发生。否则,编译器需要从其打包区域中屏蔽相应的位,并将其作为真正的bool移动到某处。
假设2:编译器对一个bool值使用大于sizeof(bool)。极不可能 - 因为那时sizeof(bool)会更大。指针操作仍然是可能的,在位数组的情况下,需要实现一些其他魔术逻辑。
假设3:编译器对阵列的不同字段使用不同的大小 - 更不可能。所需的管理信息太大了。
从这3个想法我会说简单的解决方案是最好的。为了确保现在和你的程序的所有未来,编写一个小的单元测试,准确测试(例如获取第一个值的地址,将其转换为与bool具有相同大小的类型的指针,计算元素n的地址,将该地址转换回bool的指针,在那里写一些东西并与数组访问进行比较)。如果情况发生变化,你会收到通知 - 但我怀疑它会发生。
旁注 - 当然编译器总是能够分配比所需更多的内存。但是,数组仍具有该大小(它只是放在更大的内存块中)。
答案 6 :(得分:2)
在裸骨C ++中,不可能。但是,我们鼓励(并且确实应该)考虑使用类来管理内存。
在C ++ 98中,您可以使用boost::scoped_array
或std::vector
(但bool
可能更喜欢std::vector<char>
)。
在C ++ 11中,您应该考虑将boost::scoped_array
替换为std::unique_ptr<bool[]>
。
问题是在那之前,除了std::vector
之外,没有人知道它们包含的数组的大小;他们只是处理记忆。
在C ++ 14中,出现了一个新的竞争者:std::dynarray
。它是std::vector
的精简版,其大小无法动态调整大小。简而言之,正是你想要的:只是数组及其长度,没有开销。
如果你最喜欢的编译器/工具链不支持dynarray
,你可以自己轻松实现它:
template <typename T>
class dynarray {
public:
// methods go here.
private:
size_t size;
std::unique_ptr<T[]> array;
}; // class dyn_array