trim 数组到 i 和 j 之间的元素
trim array to elements between i and j
经典之作,我在这里寻求优化:我有一些东西,经过一些处理我知道我只对元素 i 到 j 感兴趣。如何 trim 我的数组以最轻的方式在 fatset 中完成 deletions/freeing i 之前和 j 之后的元素内存?
我正在做嵌入式 C++,所以我可能无法编译各种类库。但 std 或 vector 事物在第一阶段受到欢迎!
我试过,数组 A trim介于 i 和 j 之间,变量 numElms 告诉我 A 中的元素数:
A = &A[i];
numElms = i-j+1;
因为这会产生不兼容错误。可以修复吗?即使修复了,是否可以为现在未使用的元素释放内存?
一点上下文:这个数组是我模块的中央数据集,它可能很重。只要模块存在,它就会存在。并且一直不需要负重。这是要做的第一件事 - 确定必须分析数据集的哪一部分,然后 trim 永久删除其余部分,永远不再使用它(直到我们得到的下一个周期一个可能完全不同大小的新数组)。
无法在标准 C++ 中更改分配的内存块大小(除非您有 POD 数据——在这种情况下,可以使用像 realloc
这样的 C 工具)。 trim 数组的唯一方法是分配新数组。 copy/move 需要元素并销毁旧数组。
您可以手动完成,也可以使用向量:
int* array = new int[10]{0,1,2,3,4,5,6,7,8,9};
std::vector<int> vec {0,1,2,3,4,5,6,7,8,9};
//We want only elements 3-5
{
int* new_array = new int[3];
std::copy(array + 3, array + 6, new_array);
delete[] array;
array = new_array;
}
vec = std::vector<int>(vec.begin()+3, vec.begin()+6);
如果您使用的是 C++11,这两种方法应该具有相同的性能。
如果你只是想删除多余的元素而不是真的想释放内存(例如你可能想稍后添加更多元素)你可以按照
但是,您应该考虑:您真的需要立即释放内存吗?您现在需要移动元素吗?你的阵列会活这么久,以至于你的程序会完全失去这段记忆吗?也许你需要一个 range
或者 perharps 一个 view
到数组内容?在许多情况下,您可以存储两个指针(或指针和大小)来表示您的 "new" 数组,同时保持旧指针一次全部释放。
当询问有关速度的问题时,您的速度可能取决于您正在使用的阵列的大小,但是:
你的最快方法是不是trim数组,只需使用A[index + i]
找到你想要的元素。
最轻的方法是:
- 分配动态数组
malloc
- 找到
i
和 j
后,将该范围复制到动态数组的头部
- 使用
realloc
将动态数组的大小调整为j - i + 1
但是您将此标记为 C++ 而不是 C,因此我相信您也对可读性和所需的编程投资感兴趣,而不是原始速度或重量。如果这是真的,那么我建议使用 vector
或 deque
.
给定 vector<thing> A
或 deque<thing> A
你可以这样做:
A.erase(cbegin(A), next(cbegin(A), i));
A.resize(j - i + 1);
经典之作,我在这里寻求优化:我有一些东西,经过一些处理我知道我只对元素 i 到 j 感兴趣。如何 trim 我的数组以最轻的方式在 fatset 中完成 deletions/freeing i 之前和 j 之后的元素内存?
我正在做嵌入式 C++,所以我可能无法编译各种类库。但 std 或 vector 事物在第一阶段受到欢迎!
我试过,数组 A trim介于 i 和 j 之间,变量 numElms 告诉我 A 中的元素数:
A = &A[i];
numElms = i-j+1;
因为这会产生不兼容错误。可以修复吗?即使修复了,是否可以为现在未使用的元素释放内存?
一点上下文:这个数组是我模块的中央数据集,它可能很重。只要模块存在,它就会存在。并且一直不需要负重。这是要做的第一件事 - 确定必须分析数据集的哪一部分,然后 trim 永久删除其余部分,永远不再使用它(直到我们得到的下一个周期一个可能完全不同大小的新数组)。
无法在标准 C++ 中更改分配的内存块大小(除非您有 POD 数据——在这种情况下,可以使用像 realloc
这样的 C 工具)。 trim 数组的唯一方法是分配新数组。 copy/move 需要元素并销毁旧数组。
您可以手动完成,也可以使用向量:
int* array = new int[10]{0,1,2,3,4,5,6,7,8,9};
std::vector<int> vec {0,1,2,3,4,5,6,7,8,9};
//We want only elements 3-5
{
int* new_array = new int[3];
std::copy(array + 3, array + 6, new_array);
delete[] array;
array = new_array;
}
vec = std::vector<int>(vec.begin()+3, vec.begin()+6);
如果您使用的是 C++11,这两种方法应该具有相同的性能。
如果你只是想删除多余的元素而不是真的想释放内存(例如你可能想稍后添加更多元素)你可以按照
但是,您应该考虑:您真的需要立即释放内存吗?您现在需要移动元素吗?你的阵列会活这么久,以至于你的程序会完全失去这段记忆吗?也许你需要一个 range
或者 perharps 一个 view
到数组内容?在许多情况下,您可以存储两个指针(或指针和大小)来表示您的 "new" 数组,同时保持旧指针一次全部释放。
当询问有关速度的问题时,您的速度可能取决于您正在使用的阵列的大小,但是:
你的最快方法是不是trim数组,只需使用A[index + i]
找到你想要的元素。
最轻的方法是:
- 分配动态数组
malloc
- 找到
i
和j
后,将该范围复制到动态数组的头部 - 使用
realloc
将动态数组的大小调整为j - i + 1
但是您将此标记为 C++ 而不是 C,因此我相信您也对可读性和所需的编程投资感兴趣,而不是原始速度或重量。如果这是真的,那么我建议使用 vector
或 deque
.
给定 vector<thing> A
或 deque<thing> A
你可以这样做:
A.erase(cbegin(A), next(cbegin(A), i));
A.resize(j - i + 1);