{ "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 }