{
"cells": [
{
"cell_type": "markdown",
"id": "9724a7e2",
"metadata": {},
"source": [
"# vo001_AdoptOrOwnMemory\n",
"In this tutorial we learn how the RVec class can be used to\n",
"adopt existing memory or allocate some.\n",
"\n",
"\n",
"\n",
"\n",
"**Author:** Danilo Piparo \n",
"This notebook tutorial was automatically generated with ROOTBOOK-izer from the macro found in the ROOT repository on Tuesday, May 19, 2026 at 08:27 PM."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "19baaadc",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:27:56.276908Z",
"iopub.status.busy": "2026-05-19T20:27:56.276793Z",
"iopub.status.idle": "2026-05-19T20:27:56.283973Z",
"shell.execute_reply": "2026-05-19T20:27:56.283428Z"
}
},
"outputs": [],
"source": [
"%%cpp -d"
]
},
{
"cell_type": "markdown",
"id": "530dfb3f",
"metadata": {},
"source": [
"We use this class for didactic purposes: upon copy, a line is printed to the terminal."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "ecf7c8f2",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:27:56.285417Z",
"iopub.status.busy": "2026-05-19T20:27:56.285308Z",
"iopub.status.idle": "2026-05-19T20:27:56.599702Z",
"shell.execute_reply": "2026-05-19T20:27:56.598972Z"
}
},
"outputs": [],
"source": [
"class UponCopyPrinter {\n",
"public:\n",
" UponCopyPrinter() = default;\n",
" UponCopyPrinter(UponCopyPrinter &&) = default;\n",
" UponCopyPrinter(const UponCopyPrinter &) { std::cout << \"Invoking copy c'tor!\" << std::endl; }\n",
"};"
]
},
{
"cell_type": "markdown",
"id": "74d29221",
"metadata": {},
"source": [
"One of the essential features of RVec is its ability of adopting and owning memory."
]
},
{
"cell_type": "markdown",
"id": "a1ed8216",
"metadata": {},
"source": [
"Let's create an RVec of UponCopyPrinter instances. We expect no printout:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "e4ae60a0",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:27:56.601730Z",
"iopub.status.busy": "2026-05-19T20:27:56.601585Z",
"iopub.status.idle": "2026-05-19T20:27:56.832578Z",
"shell.execute_reply": "2026-05-19T20:27:56.831808Z"
}
},
"outputs": [],
"source": [
"ROOT::RVec v(3);"
]
},
{
"cell_type": "markdown",
"id": "161abb26",
"metadata": {},
"source": [
"Let's adopt the memory from v into v2. We expect no printout:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "b287664c",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:27:56.834465Z",
"iopub.status.busy": "2026-05-19T20:27:56.834328Z",
"iopub.status.idle": "2026-05-19T20:27:57.041842Z",
"shell.execute_reply": "2026-05-19T20:27:57.041072Z"
}
},
"outputs": [],
"source": [
"ROOT::RVec v2(v.data(), v.size());"
]
},
{
"cell_type": "markdown",
"id": "c438f55e",
"metadata": {},
"source": [
"OK, let's check the addresses of the memory associated to the two RVecs It is the same!"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "8a9f795a",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:27:57.043758Z",
"iopub.status.busy": "2026-05-19T20:27:57.043617Z",
"iopub.status.idle": "2026-05-19T20:27:57.251254Z",
"shell.execute_reply": "2026-05-19T20:27:57.250620Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0x7f8713fb1010 and 0x7f8713fb1010\n"
]
}
],
"source": [
"std::cout << v.data() << \" and \" << v2.data() << std::endl;"
]
},
{
"cell_type": "markdown",
"id": "91b1dbee",
"metadata": {},
"source": [
"Now, upon reallocation, the RVec stops adopting the memory and starts owning it. And yes,\n",
"a copy is triggered. Indeed internally the storage of the RVec is an std::vector. Moreover,\n",
"the interface of the RVec is very, very similar to the one of std::vector: you have already\n",
"noticed it when the `data()` method was invoked, right?"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "fed72e34",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:27:57.253177Z",
"iopub.status.busy": "2026-05-19T20:27:57.253048Z",
"iopub.status.idle": "2026-05-19T20:27:57.460288Z",
"shell.execute_reply": "2026-05-19T20:27:57.459645Z"
}
},
"outputs": [],
"source": [
"v2.push_back(UponCopyPrinter());"
]
},
{
"cell_type": "markdown",
"id": "f8027ae6",
"metadata": {},
"source": [
"Of course, now the addresses are different."
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "f491ba8c",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:27:57.462218Z",
"iopub.status.busy": "2026-05-19T20:27:57.462093Z",
"iopub.status.idle": "2026-05-19T20:27:57.669246Z",
"shell.execute_reply": "2026-05-19T20:27:57.668640Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0x7f8713fb1010 and 0x7f86c5359800\n"
]
}
],
"source": [
"std::cout << v.data() << \" and \" << v2.data() << std::endl;"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "ROOT C++",
"language": "c++",
"name": "root"
},
"language_info": {
"codemirror_mode": "text/x-c++src",
"file_extension": ".C",
"mimetype": " text/x-c++src",
"name": "c++"
}
},
"nbformat": 4,
"nbformat_minor": 5
}