在这两种情况下,我都使用完全相同的2d数组(它是类的一个字段)。第二个lsh_distances不让我在析构函数中delete[]内部的一维数组,并给出了一个错误free(): invalid size Aborted (core dumped)。如果我不使用delete[]循环来检查内部数组,我当然会有内存泄漏(用valgrind检查)。
为什么一个地球会发生这种情况?这没有任何意义。我不会在其他地方删除lsh_distances,实际上我可以在析构函数中打印这些值。
帮助
下面是代码。
long long int NearestNeighboursSearch::calculate_exact_distances() {
unsigned int q_size = query_dataset.points.size();
unsigned int ind_size = index_dataset.points.size();
exact_distances = new long double*[q_size];
for (int i = 0 ; i < q_size ; i++) {
exact_distances[i] = new long double[ind_size];
}
chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
for (int i = 0 ; i < q_size ; i++) {
for (int j = 0 ; j < ind_size ; j++) {
exact_distances[i][j] = used_distance(*query_dataset.points.at(i), *index_dataset.points.at(j));
}
}
chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
return chrono::duration_cast<chrono::milliseconds>(end - begin).count();
}
long long int NearestNeighboursSearch::calculate_lsh_distances() {
unsigned int q_size = query_dataset.points.size();
unsigned int ind_size = index_dataset.points.size();
lsh_distances = new long double*[q_size];
for (int i = 0 ; i < q_size ; i++) {
lsh_distances[i] = new long double[ind_size];
for (int j = 0 ; j < ind_size ; j++) {
lsh_distances[i][j] = -1.0; // not calculated
}
}
// calculate and fill only distances between points that hash into the same bucket for the L hash tables
chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
for (int i = 0 ; i < q_size ; i++) {
Point *p1 = query_dataset.points.at(i);
Bucket **buckets = index_dataset.get_buckets_for_point(p1); // L buckets
for (int j = 0 ; j < index_dataset.get_hashtables_count(); j++) {
for (int k = 0 ; k < buckets[j]->points.size() ; k++) { // might be empty
const Point *p2 = buckets[j]->points[k];
// update appropriate distance at [i, p2->pos]
lsh_distances[i][p2->pos] = used_distance(*p1, *p2);
}
}
delete[] buckets;
}
chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
return chrono::duration_cast<chrono::milliseconds>(end - begin).count();
}
NearestNeighboursSearch::~NearestNeighboursSearch() {
if (exact_distances != NULL) {
for (int i = 0; i < query_dataset.points.size(); i++) {
delete[] exact_distances[i];
}
delete[] exact_distances;
}
if (lsh_distances != NULL) {
// TODO: Somehow this causes an error (it makes no sense to me)
for (int i = 0; i < query_dataset.points.size(); i++) {
delete[] lsh_distances[i];
}
delete[] lsh_distances;
}
}编辑:根据建议,我使用valgrind运行了一次。我得到了这个:
==376== Invalid write of size 4
==376== at 0x11508A: NearestNeighboursSearch::calculate_lsh_distances() (neighbour_search.cpp:66)
==376== by 0x10B2CA: main (lsh_main.cpp:132)
==376== Address 0x4e385c0 is 16 bytes before a block of size 160 alloc'd
==376== at 0x483C583: operator new[](unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==376== by 0x114F17: NearestNeighboursSearch::calculate_lsh_distances() (neighbour_search.cpp:52)
==376== by 0x10B2CA: main (lsh_main.cpp:132)
==376==
==376== Invalid write of size 2
==376== at 0x11508A: NearestNeighboursSearch::calculate_lsh_distances() (neighbour_search.cpp:66)
==376== by 0x10B2CA: main (lsh_main.cpp:132)
==376== Address 0x4e385c8 is 8 bytes before a block of size 160 alloc'd
==376== at 0x483C583: operator new[](unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==376== by 0x114F17: NearestNeighboursSearch::calculate_lsh_distances() (neighbour_search.cpp:52)
==376== by 0x10B2CA: main (lsh_main.cpp:132)
==376==我会调查这件事。似乎p2->pos以某种方式小于0。
发布于 2021-11-06 16:24:38
好的。多亏了评论和valgrind,我找到了原因。在其他地方的一个粗心的错误之后,p2->pos被-1了,我可能覆盖了一些重要的东西。逻辑已恢复。
https://stackoverflow.com/questions/69865751
复制相似问题