{"id":5086,"date":"2016-12-18T17:56:21","date_gmt":"2016-12-18T17:56:21","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/std-array-dynamic-memory-no-thanks\/"},"modified":"2023-06-26T12:31:37","modified_gmt":"2023-06-26T12:31:37","slug":"std-array-dynamic-memory-no-thanks","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/std-array-dynamic-memory-no-thanks\/","title":{"rendered":"std::array &#8211; Dynamic Memory, no Thanks"},"content":{"rendered":"<p><span style=\"font-family: courier new,courier;\">std::array<\/span> combines the best of two worlds. On the one hand, <span style=\"font-family: courier new,courier;\">std::array<\/span> has the size and efficiency of a C array; on the other hand, <span style=\"font-family: courier new,courier;\">std::array<\/span> has the interface of a <span style=\"font-family: courier new,courier;\">std::vector.<\/span>&nbsp;<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-family: courier new,courier;\">std::array<\/span> has a unique characteristic among all sequential containers of the Standard Template Library. You can not adjust its size during runtime. There are special rules for its initialization.<\/p>\n<h2>The initialization<\/h2>\n<p>You have to keep the rule for aggregate initialization in mind:<\/p>\n<ul>\n<li><span style=\"font-family: courier new,courier;\"><strong>std::array&lt;int,10&gt; arr<\/strong><\/span>: The ten elements are not initialized.<\/li>\n<li><strong><span style=\"font-family: courier new,courier;\">std::array&lt;int,10&gt;arr{}<\/span><\/strong>. The ten elements are value-initialized.<\/li>\n<li><strong><span style=\"font-family: courier new,courier;\">std::array&lt;int,10&gt;arr{1,2,3,4<\/span>)<\/strong>: The remaining elements are value-initialized.<\/li>\n<\/ul>\n<p>&nbsp;As a sequential container, std::array supports index access.<\/p>\n<h2>Index access<\/h2>\n<p>std::array <strong><span style=\"font-family: courier new,courier;\">arr<\/span><\/strong> supports the index access in three ways.<\/p>\n<ul>\n<li><strong><span style=\"font-family: courier new,courier;\">arr[n-1]: <\/span><\/strong>Access to the nth element without a check of the array boundaries.<\/li>\n<li><strong><span style=\"font-family: courier new,courier;\">arr.at(n-1):<\/span><\/strong> Access the nth element by checking the array boundaries. Eventually, a <span style=\"font-family: courier new,courier;\">std::range_error <\/span>exception is thrown.<\/li>\n<li><strong><span style=\"font-family: courier new,courier;\">std::get&lt;n-1&gt;(arr):<\/span><\/strong> Access the nth element by checking the array boundaries at compile time. The syntax is according to <span style=\"font-family: courier new,courier;\">std::tuple.<\/span><\/li>\n<\/ul>\n<p><span style=\"font-family: courier new,courier;\">std::get&lt;n&gt;(arr)<\/span> shows the relationship of <span style=\"font-family: courier new,courier;\">std::array<\/span> with <span style=\"font-family: courier new,courier;\">std::tuple<\/span>.&nbsp; <span style=\"font-family: courier new,courier;\">std::array<\/span> is a <strong>homogeneous<\/strong> container of fixed size; <span style=\"font-family: courier new,courier;\"><a href=\"http:\/\/en.cppreference.com\/w\/cpp\/utility\/tuple\">std::tuple<\/a><\/span> is a <strong>heterogeneous<\/strong> container of fixed size.<\/p>\n<p>I claimed that the C++ array is as memory efficient as a C array. The proof is still missing.<\/p>\n<\/p>\n<h2>Memory efficiency<\/h2>\n<p>My small program compares the memory efficiency of a C array, a C++ array, and a <span style=\"font-family: courier new,courier;\">std::vector.<\/span><\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30\r\n31\r\n32<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ sizeof.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;array&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;vector&gt;<\/span>\r\n \r\n \r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n  \r\n  std::cout &lt;&lt; std::endl;\r\n  \r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"sizeof(int)= \"<\/span> &lt;&lt; <span style=\"color: #0000ff;\">sizeof<\/span>(<span style=\"color: #2b91af;\">int<\/span>) &lt;&lt; std::endl;\r\n  \r\n  std::cout &lt;&lt; std::endl;\r\n  \r\n  <span style=\"color: #2b91af;\">int<\/span> cArr[10]= {1,2,3,4,5,6,7,8,9,10};\r\n  \r\n  std::array&lt;<span style=\"color: #2b91af;\">int<\/span>,10&gt; cppArr={1,2,3,4,5,6,7,8,9,10};\r\n  \r\n  std::vector&lt;<span style=\"color: #2b91af;\">int<\/span>&gt; cppVec={1,2,3,4,5,6,7,8,9,10};\r\n  \r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"sizeof(cArr)= \"<\/span> &lt;&lt; <span style=\"color: #0000ff;\">sizeof<\/span>(cArr) &lt;&lt; std::endl;  \r\n  \r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"sizeof(cppArr)= \"<\/span> &lt;&lt; <span style=\"color: #0000ff;\">sizeof<\/span>(cppArr) &lt;&lt; std::endl;\r\n  \r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"sizeof(cppVec) = \"<\/span>   &lt;&lt; <span style=\"color: #0000ff;\">sizeof<\/span>(cppVec) + <span style=\"color: #0000ff;\">sizeof<\/span>(<span style=\"color: #2b91af;\">int<\/span>)*cppVec.capacity() &lt;&lt; std::endl;\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"               = sizeof(cppVec): \"<\/span> &lt;&lt; <span style=\"color: #0000ff;\">sizeof<\/span>(cppVec) &lt;&lt; std::endl;\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"               + sizeof(int)* cppVec.capacity(): \"<\/span>   &lt;&lt; <span style=\"color: #0000ff;\">sizeof<\/span>(<span style=\"color: #2b91af;\">int<\/span>)* cppVec.capacity() &lt;&lt; std::endl;\r\n\r\n  std::cout &lt;&lt; std::endl;\r\n  \r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The numbers speak a clear language.<\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5081\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/sizeof.png\" alt=\"sizeof\" width=\"448\" height=\"208\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/sizeof.png 448w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/sizeof-300x139.png 300w\" sizes=\"auto, (max-width: 448px) 100vw, 448px\" \/><\/p>\n<p>Both the C array (line 22) and the C++ array (line 24) take 40 bytes. That is precisely <span style=\"font-family: courier new,courier;\">sizeof(int)*10.<\/span> In opposite to them, <span style=\"font-family: courier new,courier;\">std::vector<\/span> needs additional 24 bytes (line 27) to manage its data on the heap.<span style=\"font-family: courier new,courier;\"> <\/span><span style=\"font-family: courier new,courier;\">cppVec.capacity()<\/span> is the number of elements a <span style=\"font-family: courier new,courier;\">std::vector cppVec<\/span> can have without acquiring new memory. I described the details of the memory management of <span style=\"font-family: courier new,courier;\">std::vector<\/span> and <span style=\"font-family: courier new,courier;\">std::string<\/span> in the post <a href=\"https:\/\/www.modernescpp.com\/index.php\/automatic-memory-management-with-containers\">Automatic memory management of the STL containers<\/a>.<\/p>\n<p>Before I complete the picture and show the example, I want to emphasize it explicitly<strong>: The great value of a <span style=\"font-family: courier new,courier;\">std::array<\/span> in opposition to a&nbsp; C array is that <span style=\"font-family: courier new,courier;\">std::array<\/span> knows it size.<\/strong><\/p>\n<h2>std::array in action<\/h2>\n<p>One additional value of a <span style=\"font-family: courier new,courier;\">std::array<\/span> compared to a C array is that a <span style=\"font-family: courier new,courier;\">std::array<\/span> feels like a <span style=\"font-family: courier new,courier;\">std::vector.<\/span><span style=\"font-family: courier new,courier;\"><\/span><\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ array.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;algorithm&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;array&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n\r\n  std::cout &lt;&lt; std::endl;\r\n\r\n  <span style=\"color: #008000;\">\/\/ output the array<\/span>\r\n  std::array &lt;<span style=\"color: #2b91af;\">int<\/span>,8&gt; array1{1,2,3,4,5,6,7,8};\r\n  std::for_each( array1.begin(),array1.end(),[](<span style=\"color: #2b91af;\">int<\/span> v){std::cout &lt;&lt; v &lt;&lt; <span style=\"color: #a31515;\">\" \"<\/span>;});\r\n\r\n  std::cout &lt;&lt; std::endl;\r\n\r\n  <span style=\"color: #008000;\">\/\/ calculate the sum of the array by using a global variable<\/span>\r\n  <span style=\"color: #2b91af;\">int<\/span> sum = 0;\r\n  std::for_each(array1.begin(), array1.end(),[&amp;sum](<span style=\"color: #2b91af;\">int<\/span> v) { sum += v; });\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"sum of array{1,2,3,4,5,6,7,8}: \"<\/span> &lt;&lt; sum &lt;&lt; std::endl;\r\n\r\n  <span style=\"color: #008000;\">\/\/ change each array element to the second power<\/span>\r\n  std::for_each(array1.begin(), array1.end(),[](<span style=\"color: #2b91af;\">int<\/span>&amp; v) { v=v*v; });\r\n  std::for_each( array1.begin(),array1.end(),[](<span style=\"color: #2b91af;\">int<\/span> v){std::cout &lt;&lt; v &lt;&lt; <span style=\"color: #a31515;\">\" \"<\/span>;});\r\n  std::cout &lt;&lt; std::endl;\r\n\r\n  std::cout &lt;&lt; std::endl;\r\n\r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Therefore, you can output <span style=\"font-family: courier new,courier;\">array1 <\/span>in line 13 with a lambda function and the range-based for-loop. Using the summation variable <span style=\"font-family: courier new,courier;\">sum<\/span> in line 19, you can sum up the elements of the <span style=\"font-family: courier new,courier;\">std::array.<\/span> The lambda function in line 23 takes its arguments by reference and can therefore map each element to its square. Nothing special, but we are dealing with a <span style=\"font-family: courier new,courier;\">std::array.<\/span><\/p>\n<p>And here is the output of the program.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5085\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/array.png\" alt=\"array\" style=\"margin: 15px;\" width=\"471\" height=\"213\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/array.png 471w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/array-300x136.png 300w\" sizes=\"auto, (max-width: 471px) 100vw, 471px\" \/><\/p>\n<h3>For clarification<\/h3>\n<p>With C++11, we have the free function templates <a href=\"http:\/\/en.cppreference.com\/w\/cpp\/iterator\/begin\">std::begin<\/a> and <a href=\"http:\/\/en.cppreference.com\/w\/cpp\/iterator\/end\">std::end<\/a> returning iterators for a C array. So a C array is quite comfortable and safe to use with these function templates because you do have not to remember its size.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ cArray.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;algorithm&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n\r\n  std::cout &lt;&lt; std::endl;\r\n\r\n  <span style=\"color: #008000;\">\/\/ output the array<\/span>\r\n  <span style=\"color: #2b91af;\">int<\/span> array1[] = { 1, 2, 3, 4, 5, 6 ,7, 8};\r\n  std::for_each( std::begin(array1), std::end(array1), [](<span style=\"color: #2b91af;\">int<\/span> v){ std::cout &lt;&lt; v &lt;&lt; <span style=\"color: #a31515;\">\" \"<\/span>; });\r\n\r\n  std::cout &lt;&lt; std::endl;\r\n\r\n  <span style=\"color: #008000;\">\/\/ calculate the sum of the array by using a global variable<\/span>\r\n  <span style=\"color: #2b91af;\">int<\/span> sum = 0;\r\n  std::for_each(std::begin(array1), std::end(array1), [&amp;sum](<span style=\"color: #2b91af;\">int<\/span> v) { sum += v; });\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"sum of array{1, 2, 3, 4, 5, 6, 7, 8}: \"<\/span> &lt;&lt; sum &lt;&lt; std::endl;\r\n\r\n  <span style=\"color: #008000;\">\/\/ change each array element to the second power<\/span>\r\n  std::for_each(std::begin(array1), std::end(array1), [](<span style=\"color: #2b91af;\">int<\/span>&amp; v) { v=v*v; });\r\n  std::for_each(std::begin(array1), std::end(array1), [](<span style=\"color: #2b91af;\">int<\/span> v){ std::cout &lt;&lt; v &lt;&lt; <span style=\"color: #a31515;\">\" \"<\/span>; });\r\n  std::cout &lt;&lt; std::endl;\r\n\r\n  std::cout &lt;&lt; std::endl;\r\n  \r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Of course, the result is the same.<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>This post was concise. In the <a href=\"https:\/\/www.modernescpp.com\/index.php\/copy-versus-move-semantic-a-few-numbers\">next post<\/a><span id=\"transmark\">, <\/span>I will look closely at one of the prominent C++11 features: move semantic.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<span><a href=\"https:\/\/www.modernescpp.com\/index.php\/source-code-repository\"><\/a><\/span><\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>std::array combines the best of two worlds. On the one hand, std::array has the size and efficiency of a C array; on the other hand, std::array has the interface of a std::vector.&nbsp;<\/p>\n","protected":false},"author":21,"featured_media":5081,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[364],"tags":[498],"class_list":["post-5086","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-embedded","tag-memory"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5086","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=5086"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5086\/revisions"}],"predecessor-version":[{"id":6911,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5086\/revisions\/6911"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5081"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5086"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5086"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5086"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}