Skip to content

Commit c3aad36

Browse files
committed
Fix index copy constructor by retaining array based index
Array based indexing caused segfaults sometimes when the index object was not immidiately consumed by the indexing operations. This PR fixes this by retaining the index array on the copy constructor
1 parent 11148d7 commit c3aad36

2 files changed

Lines changed: 21 additions & 2 deletions

File tree

src/api/cpp/index.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,13 @@ index::index(const af::array &idx0) : impl{} {
6666
impl.isBatch = false;
6767
}
6868

69-
index::index(const af::index &idx0) : impl{idx0.impl} {} // NOLINT
69+
index::index(const af::index &idx0) : impl{idx0.impl} {
70+
if (!impl.isSeq && impl.idx.arr) {
71+
// increment reference count to avoid double free
72+
// when/if idx0 is destroyed
73+
AF_THROW(af_retain_array(&impl.idx.arr, impl.idx.arr));
74+
}
75+
}
7076

7177
// NOLINTNEXTLINE(hicpp-noexcept-move, performance-noexcept-move-constructor)
7278
index::index(index &&idx0) : impl{idx0.impl} { idx0.impl.idx.arr = nullptr; }
@@ -79,7 +85,7 @@ index &index::operator=(const index &idx0) {
7985
if (this == &idx0) { return *this; }
8086

8187
impl = idx0.get();
82-
if (!impl.isSeq) {
88+
if (!impl.isSeq && impl.idx.arr) {
8389
// increment reference count to avoid double free
8490
// when/if idx0 is destroyed
8591
AF_THROW(af_retain_array(&impl.idx.arr, impl.idx.arr));

test/index.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1764,6 +1764,19 @@ TEST(Index, ISSUE_2273_Flipped) {
17641764
ASSERT_ARRAYS_EQ(input_slice_gold, input_slice);
17651765
}
17661766

1767+
TEST(Index, CopiedIndexDestroyed) {
1768+
array in = randu(10, 10);
1769+
array a = constant(1, 10);
1770+
1771+
af::index index1(a);
1772+
af::index index2(seq(10));
1773+
1774+
af::index index3(index1);
1775+
{ af::index index4(index1); }
1776+
1777+
af_print(in(index1, index2));
1778+
}
1779+
17671780
// clang-format off
17681781
class IndexDocs : public ::testing::Test {
17691782
public:

0 commit comments

Comments
 (0)