VectorImpl::~VectorImpl() { ALOGW_IF(mCount, "[%p] subclasses of VectorImpl must call finish_vector()" " in their destructor. Leaking %d bytes.", this, (int)(mCount*mItemSize)); // We can't call _do_destroy() here because the vtable is already gone. }
after insert capacity is 4, size is 1 after insert capacity is 4, size is 2 after insert capacity is 4, size is 3 after insert capacity is 4, size is 4 after insert capacity is 8, size is 5 after insert capacity is 8, size is 6 after insert capacity is 8, size is 7 after insert capacity is 8, size is 8 after insert capacity is 14, size is 9 after insert capacity is 14, size is 10 after insert capacity is 14, size is 11 after insert capacity is 14, size is 12 after insert capacity is 14, size is 13 after insert capacity is 14, size is 14 after insert capacity is 23, size is 15
触发了2次扩容,更新规则在VectorImpl.cpp的_grow函数里,当capacity不足时,按照公式扩大容量,所以storage的长度其实是可以被预测的。扩展时使用SharedBuffer,也就是简单的malloc/memcpy/free,在memcpy的时候复制数据。例如我们这里最开始capacity是0,4,8,14,23这样的,这个按照 x + x/2 + 1 计算 ,使用safe_add宏,为什么4变成8、8变成14,可能是可能是向上取整,细节也懒得深究了。
after del capacity is 23, size is 14 after del capacity is 23, size is 13 after del capacity is 23, size is 12 after del capacity is 23, size is 11 after del capacity is 20, size is 10 after del capacity is 18, size is 9 after del capacity is 16, size is 8 after del capacity is 14, size is 7 after del capacity is 12, size is 6 after del capacity is 10, size is 5 after del capacity is 8, size is 4 after del capacity is 6, size is 3 after del capacity is 4, size is 2 after del capacity is 4, size is 1 after del capacity is 4, size is 0 after del capacity is 4, size is 0
after del capacity is 23, size is 21, ptr is 0x5c26018 after del capacity is 23, size is 20, ptr is 0x5c26018 after del capacity is 23, size is 19, ptr is 0x5c26018 after del capacity is 23, size is 18, ptr is 0x5c26018 after del capacity is 23, size is 17, ptr is 0x5c26018 after del capacity is 23, size is 16, ptr is 0x5c26018 after del capacity is 23, size is 15, ptr is 0x5c26018 after del capacity is 23, size is 14, ptr is 0x5c26018 after del capacity is 23, size is 13, ptr is 0x5c26018 after del capacity is 23, size is 12, ptr is 0x5c26018 after del capacity is 23, size is 11, ptr is 0x5c26018 after del capacity is 20, size is 10, ptr is 0x5c39018 after del capacity is 18, size is 9, ptr is 0x5c2d078 after del capacity is 16, size is 8, ptr is 0x5c2d0d8 after del capacity is 14, size is 7, ptr is 0x5c34018 after del capacity is 12, size is 6, ptr is 0x5c34068 after del capacity is 10, size is 5, ptr is 0x5c33018 after del capacity is 8, size is 4, ptr is 0x5c33058 after del capacity is 6, size is 3, ptr is 0x5c277f8 after del capacity is 4, size is 2, ptr is 0x5c27828 after del capacity is 4, size is 1, ptr is 0x5c277f8 after del capacity is 4, size is 0, ptr is 0x5c277f8 after del capacity is 4, size is 0, ptr is 0x5c277f8
void* VectorImpl::editArrayImpl() { if (mStorage) { const SharedBuffer* sb = SharedBuffer::bufferFromData(mStorage); SharedBuffer* editable = sb->attemptEdit(); if (editable == 0) { // If we're here, we're not the only owner of the buffer. // We must make a copy of it. editable = SharedBuffer::alloc(sb->size()); // Fail instead of returning a pointer to storage that's not // editable. Otherwise we'd be editing the contents of a buffer // for which we're not the only owner, which is undefined behaviour. LOG_ALWAYS_FATAL_IF(editable == NULL); _do_copy(editable->data(), mStorage, mCount); release_storage(); mStorage = editable->data(); } } return mStorage; }