Skip to content

Commit 9f4a1ea

Browse files
committed
[ntuple] fix RVec resize from small to large vector
Resizing needs to check if the previous buffer pointed to the small vector space before releasing the memory.
1 parent 437afad commit 9f4a1ea

2 files changed

Lines changed: 34 additions & 4 deletions

File tree

tree/ntuple/src/RFieldSequenceContainer.cxx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -292,10 +292,7 @@ unsigned char *ROOT::RRVecField::ResizeRVec(void *rvec, std::size_t nItems, std:
292292
}
293293

294294
// TODO Increment capacity by a factor rather than just enough to fit the elements.
295-
if (owns) {
296-
// *beginPtr points to the array of item values (allocated in an earlier call by the following malloc())
297-
free(*beginPtr);
298-
}
295+
Internal::DestroyRVecWithChecks(itemField->GetAlignment(), beginPtr, capacityPtr);
299296
// We trust that malloc returns a buffer with large enough alignment.
300297
// This might not be the case if T in RVec<T> is over-aligned.
301298
*beginPtr = static_cast<unsigned char *>(malloc(nItems * itemSize));

tree/ntuple/test/rfield_vector.cxx

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,39 @@ TEST(RNTuple, RVec)
203203
EXPECT_EQ(1.0, (*rdJetsAsStdVector)[0]);
204204
}
205205

206+
TEST(RNTuple, RVecResizeSmall)
207+
{
208+
FileRaii fileGuard("test_ntuple_rvec_small.root");
209+
210+
constexpr int N = 260; // more elements than fit in any small vector storage
211+
212+
{
213+
auto model = RNTupleModel::Create();
214+
auto v = model->MakeField<ROOT::RVec<int>>("v");
215+
for (int i = 0; i < N; ++i) {
216+
v->push_back(i);
217+
}
218+
219+
auto writer = RNTupleWriter::Recreate(std::move(model), "ntpl", fileGuard.GetPath());
220+
writer->Fill();
221+
}
222+
223+
auto reader = RNTupleReader::Open("ntpl", fileGuard.GetPath());
224+
EXPECT_EQ(1U, reader->GetNEntries());
225+
226+
ROOT::RVec<int> v;
227+
EXPECT_TRUE(ROOT::Detail::VecOps::IsSmall(v));
228+
auto e = reader->CreateEntry();
229+
e->BindRawPtr("v", &v);
230+
231+
reader->LoadEntry(0, *e);
232+
ASSERT_EQ(v.size(), N);
233+
EXPECT_FALSE(ROOT::Detail::VecOps::IsSmall(v));
234+
for (int i = 0; i < N; ++i) {
235+
EXPECT_EQ(i, v[i]);
236+
}
237+
}
238+
206239
TEST(RNTuple, RVecTypeErased)
207240
{
208241
FileRaii fileGuard("test_ntuple_rvec_typeerased.root");

0 commit comments

Comments
 (0)