数组的内存管理技巧
这是我第一次使用 stackoverflow 来回答问题,我之前读过一些答案,这些答案在某些情况下对我有帮助,所以我想我应该注册一下,因为我找不到我正在寻找的具体答案。最近,我制作了一个非常简单的粒子系统,它会喷出 100 到 1000 个粒子,只是为了看看我是否可以做到这一点,在我开始之前,我制作了一个简单的链接列表,它使用模板,这样我就可以在其他程序中使用它,如果我就这样选择
最近,在看到我的一位同事在玩粒子系统后,他发现我决定重新审视我的项目以改进它。我在互联网上搜索找到了一个小例子,它显然放弃了使用链接列表的想法,而是使用数组和三个指针来管理粒子。我理解大部分概念,但由于某种原因,我忽略了一件事。
/// the first particle in the linked list
Particle* start=0;
/// the next free particle
Particle* last=0;
/// the end of the memory allocation
Particle* end=0;
void SetSize(unsigned int size) {
// delete any previous data
delete [] start;
// allocate new particles
last = start = new Particle[size];
// set end
end = start+size;
}
void AddOne() {
// if we have no more memory left for any particles, ignore
// the request to creat one.
if (!IsFull()) {
*last = Particle();
++last;
}
}
void EraseOne(Particle* p) {
if (!IsEmpty()) {
*p = *(--last);
}
}
根据我对上面代码的理解,这三个指针充当指向数组中元素的简单指针。起始指针保持为零,结束指针保持在数组的末尾,而最后一个指针从与起始指针相同的位置开始,并像索引计数器一样移动,直到到达末尾。
我不确定的是擦除位,我从上面的代码中假设“p”不是最后一个指针指向的粒子,而是最后一个之前的粒子。不幸的是,我不知道为什么要这样做,因为最后一个肯定是一个完全活跃的粒子,但这不会产生同一粒子的两个实例吗?
This is my first time using stackoverflow for a question, I have read a few answers previously which have helped me in some cases so I thought I'd register seeing as I can't find the specific answer I'm looking for. Recently I made a pretty simple particles system that spews out a couple 100 to 1000s of particles just to see if I could do it, before I even started this I made a simple Linked List which uses templates so I can use it in other programs if I so choose.
Recently, after seeing a colleague of mine playing about with a particle system he found I decided to revisit my project to improve upon it. I scoured the internet to find a little example which apparently ditches the idea of using a Linked List and instead uses and array and three pointers to manage the particles. I understand most of the concept but for some reason one thing escapes me.
/// the first particle in the linked list
Particle* start=0;
/// the next free particle
Particle* last=0;
/// the end of the memory allocation
Particle* end=0;
void SetSize(unsigned int size) {
// delete any previous data
delete [] start;
// allocate new particles
last = start = new Particle[size];
// set end
end = start+size;
}
void AddOne() {
// if we have no more memory left for any particles, ignore
// the request to creat one.
if (!IsFull()) {
*last = Particle();
++last;
}
}
void EraseOne(Particle* p) {
if (!IsEmpty()) {
*p = *(--last);
}
}
From what I understand from the code above the three pointers act as simple pointers to the elements in the array. The start pointer remains at zero and the end pointer remains at the end of the array while last starts from the same position as the start pointer and moves along like an index counter until it gets to the end.
What I'm unsure of is the erasing bit, I assume from the code above that 'p' is becoming not the particle the last pointer is pointing to but the one before last. Unfortunately I have no idea why it is done this way as surely the one before last is a perfectly alive particle but wouldn't this make two instances of the same particle?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,您应该使用标准容器,而不是尝试半成品的手动实现。现在解释一下代码:
该代码显示了一个常见的模式。基本上,您使用三个指针,一个指向已分配内存的开头(相当于
begin()
),一个超出最后一个元素的指针(相当于end()
)第三个指针超出最后分配的块(以避免溢出。考虑到这一点,解释函数并不难。特别是
AddOne
(类似于push_back
但没有增加缓冲区)更新第一个元素超出末尾,并递增指针以引用超出新的最后一个元素的元素,从
EraseOne
基本上执行相反的操作:它首先递减指针(因此现在 previouslast 元素位于该元素之外。有效范围),然后复制该元素(请记住,指针指向末尾之外的元素)The first thing is that you should use a standard continer rather than trying a half baked manual implementation. Now to the interpretation of the code:
The code shows a common pattern. Basically you use three pointers, one to the beginning of the allocated memory, (equivalent to
begin()
), a pointer one beyond the last element (equivalent toend()
and a third pointer one beyond the last allocated block (to avoid overflowing.With that in mind interpreting the functions is not hard. In particular,
AddOne
(similar topush_back
but without growing the buffer) updates the first element beyond the end, and increments the pointer to refer to one beyond the new last element.As of
EraseOne
basically performs the reverse operation: it first decrements the pointer (so now the previouslast element is outside of the valid range) and then copies that element (remember that the pointer refers to one beyond the end)