无法解释的free():C++中delete[]中的大小无效



在这两种情况下,我使用完全相同的2d数组(它是类的一个字段(。第二个lsh_distances不允许我删除析构函数中的内部1d数组,并给出free(): invalid size Aborted (core dumped)的错误。如果我不使用for循环来删除[]内部数组,我当然会有内存泄漏(用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不知怎么的。

好的。多亏了评论和勇气,我才明白为什么。p2->pos-1,因为我在其他地方犯了一个粗心的错误,我可能在写一些重要的东西。逻辑已恢复。

最新更新