{"id":8177,"date":"2023-01-09T11:09:38","date_gmt":"2023-01-09T10:09:38","guid":{"rendered":"https:\/\/playembedded.org\/?p=8177"},"modified":"2024-01-17T09:41:25","modified_gmt":"2024-01-17T08:41:25","slug":"demystifying-c-pointers","status":"publish","type":"post","link":"https:\/\/playembedded.org\/blog\/demystifying-c-pointers\/","title":{"rendered":"Demystifying C: Pointers"},"content":{"rendered":"<h2 class=\"wp-block-heading level_1\" id=\"1_Introduction\">Introduction<\/h2>\n\n\n\n<p>In our <a href=\"https:\/\/playembedded.org\/demystifying-c-types\/\" data-type=\"post\" data-id=\"8079\">last article<\/a> in the series Demystifying C, we discussed the various types available in the C programming language. In this article, we&rsquo;ll build on that foundation by exploring a concept that can be intimidating for C-newbies: pointers<\/p>\n\n\n\n<p>Pointers can be a daunting concept for those new to the C programming language, but they are a very powerful tool that can greatly improve the efficiency of your code. In this article, we will demystify pointers and explain how they work, why they are useful, and how to use them in your C programs.<\/p>\n\n\n\n<p>Whether you are a beginner looking to improve your understanding of pointers or an experienced programmer looking to refresh your knowledge, this article has something for you.<\/p>\n\n\n\n<p>So let us get started on demystifying pointers in C!<\/p>\n\n\n\n<h2 class=\"wp-block-heading level_1\" id=\"2_What_is_a_pointer\">What is a pointer<\/h2>\n\n\n\n<p>A <strong>pointer<\/strong> is a particular type of variable in C that stores the memory address of another variable (as its name suggests a pointer points to a memory address). They are commonly used to manipulate data stored in arrays and structures, as well as to pass large blocks of data to functions more efficiently.<\/p>\n\n\n\n<p>Some typical use cases for pointers include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Accessing elements of an array.<\/li>\n\n\n\n<li>Implementing dynamic memory allocation.<\/li>\n\n\n\n<li>Building complex data structures.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading level_2\" id=\"3_Declaration_initialization_and_access\">Declaration, initialization and access<\/h3>\n\n\n\n<p>Pointers can have different types depending on the type of variable they point to. For example, a pointer to an <code>int<\/code> can only store the memory address of an int variable, and a pointer to a double can only store the memory address of a double variable. <\/p>\n\n\n\n<p>To declare a pointer with a specific type in C, we can use the <code>*<\/code> symbol followed by the name of the pointer and the type of the variable it points to as shown below<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/* Declaration of a pointer to an integer. *\/\nint* mypointer\n\n\/* Declaration of a pointer to a char. *\/\nchar* mypointer\n\n\/* Declaration of a pointer to a double. *\/\ndouble* mypointer<\/pre>\n\n\n\n<p>Let us now consider the following code:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">int myvar = 42;\nint* mypointer = &amp;myvar;<\/pre>\n\n\n\n<p>In the first line, we just declared <code>myvar<\/code>, a regular integer variable that stores the value 42 (often referred to as the <strong>right value<\/strong> of <code>myvar<\/code>). This variable is stored in memory at a specific location, which in this example we will assume to be the address <code>0x40000080<\/code> (often referred to as the <strong>left value<\/strong> of <code>myvar<\/code>).<\/p>\n\n\n\n<p>In the second line, we declare an integer pointer called <code>mypointer<\/code> and we initialize it with the address of the <code>myvar<\/code> variable. We can hence notice that:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The <code>&amp;<\/code> operator, also known as the &ldquo;address of&rdquo; operator,  is a unary operator that returns the memory address of a given variable<\/li>\n\n\n\n<li>Initializing a pointer involves assigning it a memory address.<\/li>\n<\/ul>\n\n\n\n<p>It is worth noting that, when the memory address of a variable is known, it is possible to initialize a pointer by assigning it a constant value that represents that address<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">int* mypointer = 0x40000080;<\/pre>\n\n\n\n<p>Now that <code>mypointer<\/code> contains the memory address of <code>myvar<\/code>, it can be used to access the value stored in <code>myvar<\/code> through the use of the <code>*<\/code> operator.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include &lt;stdio.h&gt;\n\nint main(void) {\n  int myvar = 42;\n  int* mypointer = &amp;myvar;\n\n  printf(\"The value of myvar is: %d\\n\", *mypointer);\n\n  return 0;\n}<\/pre>\n\n\n\n<p>that will result in<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">The value of myvar is: 42<\/pre>\n\n\n\n<h3 class=\"wp-block-heading level_2\" id=\"4_Size_and_type\">Size and type<\/h3>\n\n\n\n<p>As mentioned previously, a pointer is a variable specifically designed to store a memory address. It should come as no surprise that pointers of different types always have the same size. The size of a pointer depends on the architecture of the machine on which the program is running. On most modern systems, pointers are typically 4 bytes (32 bits) on a 32-bit system and 8 bytes (64 bits) on a 64-bit system.<\/p>\n\n\n\n<p>An easy way to check the size of a pointer on the system in use is to exploit <code>sizeof<\/code>, a unary compile-time operator that returns the size, in bytes, of a given data type or expression.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include &lt;stdio.h&gt;\n\nint main(void) {\n\n  printf(\"Size of int*: %lu\\n\", sizeof(int*));\n  printf(\"Size of double*: %lu\\n\", sizeof(double*));\n\n  return 0;\n}<\/pre>\n\n\n\n<p>On a 32-bit architecture, this would result in<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Size of int*: 4\nSize of double*: 4<\/pre>\n\n\n\n<p>So, what is then the purpose of specifying a type while declaring a pointer?<\/p>\n\n\n\n<p>In C, the type of a pointer is important because it helps the compiler check for errors and generate correct code for accessing and manipulating the value the pointer points to. This is related to how the data is stored in memory. In modern architectures, each memory address refers to a cell of memory that is 8 bits (1 byte) in size.<\/p>\n\n\n\n<p>Let us do an example to clear up any doubts.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include &lt;stdio.h&gt;\n#include &lt;stdint.h&gt;\n\nint main(void) {\n  uint32_t myvar = 0x12345678;\n  \n  printf(\"Memory address of myvar: 0x%X\\n\", &amp;myvar);\n  return 0;\n}<\/pre>\n\n\n\n<p>and let us say that this results in<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Memory address of myvar: 0x40001000<\/pre>\n\n\n\n<p>What would the memory look like? The answer is<\/p>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\"><table><thead><tr><th class=\"has-text-align-center\" data-align=\"center\">Memory address<\/th><th class=\"has-text-align-center\" data-align=\"center\">Element Value<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\">0x40001000<\/td><td class=\"has-text-align-center\" data-align=\"center\">0x78<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">0x40001001<\/td><td class=\"has-text-align-center\" data-align=\"center\">0x56<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">0x40001002<\/td><td class=\"has-text-align-center\" data-align=\"center\">0x34<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">0x40001003<\/td><td class=\"has-text-align-center\" data-align=\"center\">0x12<\/td><\/tr><\/tbody><\/table><figcaption class=\"wp-element-caption\">Memory layout of a <code>uint32_t<\/code> variable stored at the memory address 0x40001000 with little-endian byte order<\/figcaption><\/figure>\n\n\n\n<p>In this hypothetical example, the <code>uint32_t<\/code> variable <code>myvar<\/code> occupies 4 consecutive memory addresses (4 bytes). The value of <code>myvar<\/code>, which is <code>0x12345678<\/code>, is stored in little-endian order, with the least significant byte (LSB) at the lowest memory address (<code>0x40001000<\/code>) and the most significant byte (MSB) at the highest memory address (<code>0x40001003<\/code>).<\/p>\n\n\n\n<p>This should give the astute reader an idea of where we are heading. In any case, let us extend our previous example.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include &lt;stdio.h&gt;\n#include &lt;stdint.h&gt;\n\nint main(void) {\n  uint32_t myvar = 0x12345678;\n  uint32_t* mypointer = &amp;myvar;\n  \n  printf(\"Memory address of myvar: 0x%X\\n\", &amp;myvar);\n  printf(\"Value of myvar: 0x%X\\n\", *mypointer);\n  return 0;\n}<\/pre>\n\n\n\n<p>that will print out<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Memory address of myvar: 0x40001000\nValue of myvar: 0x12345678<\/pre>\n\n\n\n<p>The pointer type is crucial for the compiler to interpret the expression <code>*mypointer<\/code>, as it determines that 4 contiguous memory cells should be loaded when dereferencing the pointer.<\/p>\n\n\n\n<p>We will see in the next section that the type of the pointer is also crucial for pointer arithmetic.<\/p>\n\n\n\n<h3 class=\"wp-block-heading level_2\" id=\"5_Pointer_arithmetic\">Pointer arithmetic<\/h3>\n\n\n\n<p><strong>Pointer arithmetic<\/strong> is a type of arithmetic that is specific to pointers in C programming. It involves performing arithmetic operations on pointers, such as incrementing <code>++<\/code>, decrementing <code>--<\/code>, adding <code>+<\/code>, and subtracting <code>-<\/code>, to manipulate and access contiguous memory areas. The astute reader may have already deduced that pointer arithmetic is particularly well-suited for handling arrays or structures.<\/p>\n\n\n\n<p>When used with pointers, these operators behave differently than when used with other types of operands. For example, adding a value to a pointer does not perform a mathematical addition, but rather moves the pointer by a certain number of elements of the data type to which the pointer points.<\/p>\n\n\n\n<p>Let us dive into some examples.<\/p>\n\n\n\n<h4 class=\"wp-block-heading level_3\" id=\"6_A_simple_increment\">A simple increment<\/h4>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include &lt;stdio.h&gt;\n#include &lt;stdint.h&gt;\n\nint main(void) {\n  uint16_t myvar = 0x1234;\n  uint16_t *mypointer = &amp;myvar;\n\n  \/* print the address of myvar using the mypointer *\/\n  printf(\"mypointer = 0x%X\\n\", mypointer);\n  \/* increment the pointer *\/\n  mypointer++;\n  \/* print the incremented address *\/\n  printf(\"mypointer = 0x%X\\n\", mypointer);\n\n  return 0;\n}<\/pre>\n\n\n\n<p>If <code>myvar<\/code> would be located at <code>0x40001000<\/code> the result of this code would be<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">mypointer = 0x40001000\nmypointer = 0x40001002<\/pre>\n\n\n\n<p>This program declares a <code>uint16_t<\/code> type variable <code>myvar<\/code> initialized to 0x1234, and a pointer <code>mypointer<\/code> to a <code>uint16_t<\/code> pointing to the address of <code>myvar<\/code>. It then prints the value of <code>mypointer<\/code>, increments it using the <code>++<\/code> operator, and it prints the pointer again.<\/p>\n\n\n\n<p>In this specific case, the value of <code>mypointer<\/code> is moved to the contiguous memory address considering the type of <code>myvar<\/code> is <code>uint16_t<\/code> (2 Bytes). <\/p>\n\n\n\n<h4 class=\"wp-block-heading level_3\" id=\"7_Type_matters\">Type matters<\/h4>\n\n\n\n<p>Let us extend the concept of the previous example by changing the type<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include &lt;stdio.h&gt;\n#include &lt;stdint.h&gt;\n\nint main(void) {\n  uint32_t myvar = 0x12345678;\n  uint32_t *mypointer = &amp;myvar;\n\n  \/* print the address of myvar using the mypointer *\/\n  printf(\"mypointer = 0x%X\\n\", mypointer);\n  \/* increment the pointer *\/\n  mypointer++;\n  \/* print the incremented address *\/\n  printf(\"mypointer = 0x%X\\n\", mypointer);\n\n  return 0;\n}<\/pre>\n\n\n\n<p>assuming again that <code>myvar<\/code> is located at <code>0x40001000<\/code> the result of this code is<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">mypointer = 0x40001000\nmypointer = 0x40001004<\/pre>\n\n\n\n<h4 class=\"wp-block-heading level_3\" id=\"8_The_Art_of_Back_and_Forth_Navigation\">The Art of Back-and-Forth Navigation<\/h4>\n\n\n\n<p>Let us consider this final example about pointer arithmetics<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include &lt;stdio.h&gt;\n#include &lt;stdint.h&gt;\n\nint main(void) {\n  uint32_t myvar = 0x12345678;\n  uint32_t *mypointer = &amp;myvar;\n\n  \/* print the address of myvar using the mypointer *\/\n  printf(\"mypointer = 0x%X\\n\", mypointer);\n  \/* add 4 to the pointer, which moves it 4 uint32_t addresses ahead *\/\n  mypointer += 4;\n  \/* print the incremented address *\/\n  printf(\"mypointer = 0x%X\\n\", mypointer);\n  \/* decrement the pointer *\/\n  mypointer--;\n  \/* print the incremented address *\/\n  printf(\"mypointer = 0x%X\\n\", mypointer);\n  return 0;\n}<\/pre>\n\n\n\n<p>in this case, with the usual assumption about <code>myvar<\/code> address, the result will be<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">mypointer = 0x40001000\nmypointer = 0x40001010\nmypointer = 0x4000100C<\/pre>\n\n\n\n<p>In other words the operation <code>mypointer += 4;<\/code> incremented the initial value of <code>mypointer<\/code> of <code>4 * sizeof(uint32_t)<\/code> and this makes the jump of <code>0x10<\/code>. The decrement operation moves the pointer back by 4 bytes.<\/p>\n\n\n\n<h2 class=\"wp-block-heading level_1\" id=\"9_Pointer_and_arrays\">Pointer and arrays<\/h2>\n\n\n\n<p>Pointers and arrays are fundamental concepts in C programming, and they are often used in conjunction with one another. In this chapter, we will compare and contrast pointer arithmetic and array indexing and will learn how to use these techniques to access and manipulate memory addresses and array elements. We will also see how pointers can be used to dynamically allocate memory for variables, including arrays, and how they can be used to manipulate strings in C.<\/p>\n\n\n\n<h3 class=\"wp-block-heading level_2\" id=\"10_Introducing_arrays\">Introducing arrays<\/h3>\n\n\n\n<p>An array is a data structure in C that allows us to store and access a fixed-size sequenced collection of elements of the same data type. Arrays are stored in contiguous blocks of memory, with each element of the array occupying a specific memory location.<\/p>\n\n\n\n<p>Let us consider the following code<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">uint16_t myarray[5] = {1, 2, 3, 4, 5};<\/pre>\n\n\n\n<p>In this example, we have declared an array <code>myarray<\/code> of five uint16_t elements and we have initialized the elements of the array with the values 1, 2, 3, 4, and 5. <\/p>\n\n\n\n<p>We can access the elements of the array using indices, with the first element of the array having an index of 0 and the last element having an index of <code>n - 1<\/code>, where <code>n<\/code> is the size of the array. For example, accessing the third element of the array will look like<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">uint16_t third_element = myarray[2];<\/pre>\n\n\n\n<p>But how it looks like the memory layout of an array? Let us assume that the elements of <code>myarray<\/code> are stored in memory starting at the address <code>0x40001000<\/code>. Then each element will occupy a contiguous block of memory as shown below:<\/p>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\"><table><thead><tr><th class=\"has-text-align-center\" data-align=\"center\">Memory Address<\/th><th class=\"has-text-align-center\" data-align=\"center\">Element Value<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\">0x40001000<\/td><td class=\"has-text-align-center\" data-align=\"center\">1<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">0x40001002<\/td><td class=\"has-text-align-center\" data-align=\"center\">2<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">0x40001004<\/td><td class=\"has-text-align-center\" data-align=\"center\">3<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">0x40001006<\/td><td class=\"has-text-align-center\" data-align=\"center\">4<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">0x40001008<\/td><td class=\"has-text-align-center\" data-align=\"center\">5<\/td><\/tr><\/tbody><\/table><figcaption class=\"wp-element-caption\">Memory layout of an array of uint16_t elements<\/figcaption><\/figure>\n\n\n\n<p>In C, an array name is automatically converted to a pointer to the first element of the array when it is used in an expression. This means that we can use the array name <code>myarray<\/code> as a pointer to access and manipulate the elements of the array. For example, if we print out the value of <code>myarray<\/code>:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include &lt;stdio.h&gt;\n#include &lt;stdint.h&gt;\n\nint main(void) {\n  uint16_t myarray[5] = {1, 2, 3, 4, 5};\n  printf(\"Memory address of myarray: 0x%X\\n\", myarray);\n  \n  return 0;\n}<\/pre>\n\n\n\n<p>The result will be<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Memory address of myarray: 0x40001000<\/pre>\n\n\n\n<p>Anyway, the array name <code>myarray<\/code> can be considered a &ldquo;pseudo-pointer&rdquo; in the sense that it behaves like a pointer in many contexts, but it is not a true pointer variable and cannot be modified like a normal one: the array name is a constant expression. This means that you cannot change the value of the array name itself, as it is a fixed memory address.<\/p>\n\n\n\n<h3 class=\"wp-block-heading level_2\" id=\"11_Exploiting_pointers_with_arrays\">Exploiting pointers with arrays<\/h3>\n\n\n\n<p>Building on this introduction to arrays, let us now explore some examples of using pointers with arrays.<\/p>\n\n\n\n<h4 class=\"wp-block-heading level_3\" id=\"12_Dereferencing_a_pointer_to_retrieve_array_elements\">Dereferencing a pointer to retrieve array elements<\/h4>\n\n\n\n<p>We can use the <code>*<\/code> operator to dereference the pointer and access the value of the first element of the array as follows:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">uint16_t first_element = *myarray;<\/pre>\n\n\n\n<p>Similarly, it is possible to use pointer algebra to access a generic element of the array. For example, the following code<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">uint16_t third_element = *(myarray + 2);<\/pre>\n\n\n\n<p>behaves exactly like<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">uint16_t third_element = myarray[2];<\/pre>\n\n\n\n<h4 class=\"wp-block-heading level_3\" id=\"13_Traversing_an_array_using_a_pointer\">Traversing an array using a pointer<\/h4>\n\n\n\n<p>If we would print the content of <code>myarray<\/code>, most likely we would write<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include &lt;stdio.h&gt;\n#include &lt;stdint.h&gt;\n\nint main(void) {\n  uint16_t myarray[5] = {1, 2, 3, 4, 5};\n\n  printf(\"Elements of myarray: \");\n  for (int i = 0; i &lt; 5; i++) {\n    printf(\"%d \", myarray[i]);\n  }\n  printf(\"\\n\");\n  return 0;\n}<\/pre>\n\n\n\n<p>the result of this code is<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Elements of myarray: 1 2 3 4 5<\/pre>\n\n\n\n<p>It is possible to perform the same operation using the array pseudo pointer and the pointer arithmetic<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include &lt;stdio.h&gt;\n#include &lt;stdint.h&gt;\n\nint main(void) {\n  uint16_t myarray[5] = {1, 2, 3, 4, 5};\n\n  printf(\"Elements of myarray: \");\n  for (int i = 0; i &lt; 5; i++) {\n    printf(\"%d \", *(myarray + i));\n  }\n  printf(\"\\n\");\n  return 0;\n}<\/pre>\n\n\n\n<h2 class=\"wp-block-heading level_1\" id=\"14_Pointer_and_functions\">Pointer and functions<\/h2>\n\n\n\n<p>In C when a function is called, a block of memory called <strong>Stack Frame<\/strong> is created to store the function&rsquo;s local variables and arguments. The stack frame is created on the top of the call stack, and it is destroyed when the function returns. This allows the function to have its own set of variables that are separate from the variables in the calling function.<\/p>\n\n\n\n<p>The take out from this statement is that, in C, arguments are passed to functions by value (call-by-value), which means that the function receives a copy of the argument: any changes that the function makes to the argument will not affect the original value of the argument in the calling function. For example the following code<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include &lt;stdio.h&gt;\n\nvoid increment(int x) {\n  x++;\n}\n\nint main() {\n  int myvar = 5;\n  increment(myvar);\n  printf(\"The value of myvar is %d\\n\", myvar);\n\n  return 0;\n}<\/pre>\n\n\n\n<p>will result in<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">The value of myvar is 5<\/pre>\n\n\n\n<p>This because <code>x<\/code> is a copy of <code>myvar<\/code> and any change in <code>increment()<\/code> is not changing the value of <code>myvar<\/code><\/p>\n\n\n\n<p>The result of the following code will clear any doubts<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include &lt;stdio.h&gt;\n\nvoid increment(int x) {\n  printf(\"The address of x is 0x%X\\r\\n\", &amp;x);\n}\n\nint main() {\n  int myvar = 5;\n  increment(myvar);\n  printf(\"The address of myvar is 0x%X\\r\\n\", &amp;myvar);\n\n  return 0;\n}<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">The address of x is 0x4000DF1C\nThe address of myvar is 0x4000AD34<\/pre>\n\n\n\n<h3 class=\"wp-block-heading level_2\" id=\"15_Modify_variables_in_a_function\">Modify variables in a function<\/h3>\n\n\n\n<p>In this specific scenario, pointers play a crucial role. Using pointers it is possible to simulate a call-by-reference behavior.  To operate on the original value within the function <code>increment<\/code>, the solution is to pass a pointer to myvar and dereference the pointer inside the function. <\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include &lt;stdio.h&gt;\n\nvoid increment(int *x) {\n  (*x)++;\n}\n\nint main() {\n  int myvar = 5;\n  increment(&amp;myvar);\n  printf(\"The value of myvar is %d\\n\", myvar);\n\n  return 0;\n}<\/pre>\n\n\n\n<p>that will now result in<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">The value of myvar is 6<\/pre>\n\n\n\n<h3 class=\"wp-block-heading level_2\" id=\"16_Returning_multiple_values_from_a_function\">Returning multiple values from a function<\/h3>\n\n\n\n<p>Similarly, we can use pointers to return multiple values from a function by modifying the values of the variables that the pointers point to. A simple example would be<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include &lt;stdio.h&gt;\n\nvoid divide(int a, int *quotient, int *remainder) {\n  *quotient = a \/ 3;\n  *remainder = a % 3;\n}\n\nint main() {\n  int x = 10;\n  int quotient;\n  int remainder;\n\n  divide(x, &amp;quotient, &amp;remainder);\n  printf(\"Quotient: %d, Remainder: %d\\n\", quotient, remainder);\n\n  return 0;\n}<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Quotient: 3, Remainder: 1<\/pre>\n\n\n\n<h3 class=\"wp-block-heading level_2\" id=\"17_Passing_large_amounts_of_data_more_efficiently\">Passing large amounts of data more efficiently<\/h3>\n\n\n\n<p>When you pass a large amount of data to a function, it can be more efficient to pass a pointer to the data rather than making a copy of the data. This is because making a copy of the data can be time-consuming and use up a lot of memory. A simple example would be<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include &lt;stdio.h&gt;\n\nstruct Data {\n  int *array;\n  size_t size;\n};\n\nvoid print_sum(struct Data *data) {\n  int sum = 0;\n  for (size_t i = 0; i &lt; data-&gt;size; i++) {\n    sum += data-&gt;array[i];\n  }\n  printf(\"Sum: %d\\n\", sum);\n}\n\nint main() {\n  int large_array[1000];\n  for (size_t i = 0; i &lt; 1000; i++) {\n    large_array[i] = i;\n  }\n\n  struct Data data = {large_array, 1000};\n  print_sum(&amp;data);\n\n  return 0;\n}<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Sum: 499500<\/pre>\n\n\n\n<h3 class=\"wp-block-heading level_2\" id=\"18_Passing_a_pointer_of_an_unknown_type_to_a_function\">Passing a pointer of an unknown type to a function<\/h3>\n\n\n\n<p>There can be situations where a function or method needs to accept a pointer to any type of object without specifying the actual type of the object. This is often done for abstraction purposes, where the type of the object is not important for the function to perform its task. In such cases, it is possible to use a &ldquo;pointer to void&rdquo; or void*. This mechanism utilizes the fact that all pointers have the same size, regardless of the type of object they point to. The type of object is only needed for accessing the data structure or performing pointer arithmetic.<\/p>\n\n\n\n<p>The following example explains how this mechanism can be used<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include &lt;stdio.h&gt;\n\nvoid print_value(void* value, int type) {\n  if(type == 1) {\n    int *int_value = (int*) value;\n    printf(\"Integer value: %d\\n\", *int_value);\n  } \n  else if(type == 2) {\n    float *float_value = (float*) value;\n    printf(\"Float value: %f\\n\", *float_value);\n  }\n}\n\nint main() {\n  int int_var = 5;\n  float float_var = 3.14;\n  print_value(&amp;int_var, 1);\n  print_value(&amp;float_var, 2);\n  return 0;\n}<\/pre>\n\n\n\n<p>In this case, the function <code>print_value<\/code> receives the value as a pointer to <code>void<\/code> and then depending on the type the pointer is cast and used. While this example may look silly, imagine that such a function is part of a library and everything will fall into place. When defining a function at the library level sometimes is not possible to know the type of data structure the function will operate on and can also be that knowing it doesn&rsquo;t make actually any difference.<\/p>\n\n\n\n<p>In this example, the function <code>print_value<\/code> accepts a pointer of type <code>void*<\/code> as an argument, which can point to any type of object. Depending on the type argument passed to the function, the <code>void*<\/code> pointer is cast to the appropriate type and used to access the value. While this example may seem simple, it demonstrates how a function at the library level can be designed to operate on any type of object without specifying the actual type of the object. This approach can be useful when it is not possible to know the type of data structure that the function will operate on, or when the specific type is not important for the function to perform its task.<br><br>To clarify this let us now consider the following example<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include &lt;string.h&gt;\n#include &lt;stdio.h&gt;\n\nint main() {\n  char src[] = \"Hello World!\";\n  char dest[20];\n  \n  memcpy(dest, src, sizeof(src));\n  printf(\"Copied string: %s\\n\", dest);\n  \n  return 0;\n}<\/pre>\n\n\n\n<p>and the prototype of the <code>memcpy<\/code> function <\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">void* memcpy(void* dest, const void* src, size_t n);<\/pre>\n\n\n\n<p>This is a standard C library function that is used to copy a block of memory (<code>n<\/code> bytes) from a source location (<code>src<\/code>) to a destination location(<code>dest<\/code>). The function can be used to copy arrays, structures, or any other type of memory block using pointers to void.<\/p>\n\n\n\n<h2 class=\"wp-block-heading level_1\" id=\"19_Pointer_and_Dynamic_allocation\">Pointer and Dynamic allocation<\/h2>\n\n\n\n<p>Pointers are key in dynamic memory allocation because they are how the allocated memory is accessed. When we allocate memory dynamically, we are requesting a block of memory from the operating system at runtime. The operating system then sets aside a block of memory for our program and returns a pointer to the first byte of that block. We can then use the pointer to access and manipulate the memory block as needed.<\/p>\n\n\n\n<p><code>malloc<\/code> is a standard C function that is used to dynamically allocate memory. It takes a single argument, which is the number of bytes of memory to allocate and returns a pointer to the allocated memory or NULL if the memory allocation fails. <\/p>\n\n\n\n<p>The following example shows how to use the <code>malloc<\/code> function to dynamically allocate memory for an array of integers:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n\nint main() {\n  int n = 10;\n  \/* Allocating memory for an array of 10 integers. *\/\n  int *array = malloc(n * sizeof(int));\n  \n  \/* As the malloc can fail returning NULL, it is good practice \n     to check the operation result. *\/\n  if (array == NULL) {\n    printf(\"malloc failed\\n\");\n    exit(1);\n  }\n\n  \/* Using the array as needed. Note I may have used\n     also the pointer arithmetic. *\/\n  for (int i = 0; i &lt; n; i++) {\n    array[i] = i * 2;\n  }\n\n  for (int i = 0; i &lt; n; i++) {\n    printf(\"%d \", array[i]);\n  }\n  printf(\"\\n\");\n\n  \/* Freeing the memory once done with it. *\/\n  free(array);\n\n  return 0;\n}<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">0 2 4 6 8 10 12 14 16 18 <\/pre>\n\n\n\n<h2 class=\"wp-block-heading level_1\" id=\"20_Common_mistakes_when_working_with_pointers\">Common mistakes when working with pointers<\/h2>\n\n\n\n<p>In this final chapter, we will explore the most common mistakes made when working with pointers and how to avoid them for seamless programming.<\/p>\n\n\n\n<h3 class=\"wp-block-heading level_2\" id=\"21_Dereferencing_a_null_pointer\">Dereferencing a null pointer<\/h3>\n\n\n\n<p>This occurs when we try to access the value at a memory address that is <code>NULL<\/code>. To avoid this mistake, we should always check that a pointer is non-null before dereferencing it.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">msg_t myfunct (int32_t* prt) {\n  if(prt == NULL) {\n    return MSG_ERROR;\n  }\n  \n  \/* Normal function execution. *\/   \n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading level_2\" id=\"22_Accessing_memory_out_of_bounds_aka_Overflow_\">Accessing memory out of bounds (aka Overflow)<\/h3>\n\n\n\n<p>This occurs when you try to access memory that is outside the bounds of the memory block that we have allocated. This problem may result in a <strong>segmentation fault<\/strong>: as the program tries to read or write to a memory location that it does not have permission to access it gets terminated with an error message. While this can be frustrating for the programmer, as it can be difficult to track down the cause of the error, faults of this type are typically the less dangerous. In some other cases, an overflow may result in unexpected behavior that may occur at a random moment in time: this category of errors may be more problematic as they may go unnoticed for a long time.<\/p>\n\n\n\n<p>Good practices that can alleviate this pain are:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Allocate enough memory to store all necessary data.<\/li>\n\n\n\n<li>Use valid array indices when working with arrays remembering that array indices start at 0 and go up to size &ndash; 1.<\/li>\n\n\n\n<li>Use appropriate loop limits especially when loops are iterating over the elements of an array.<\/li>\n\n\n\n<li>Check the return value of functions that allocate memory (such as <code>malloc<\/code>, <code>calloc<\/code>, or <code>realloc<\/code>). If the function returns <code>NULL<\/code>, it means that the memory allocation has failed and the memory should not be accessed.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading level_2\" id=\"23_Confusing_operators\">Confusing operators<\/h3>\n\n\n\n<p>Confusing the <strong>address-of<\/strong> operator <code>&amp;<\/code> and the <strong>dereference <\/strong>operator <code>*<\/code> are different. A common mistake is to use the wrong operator in the wrong context, such as using address-of trying to get the value of a variable that a pointer points to, or using dereference to get the address of a variable.<\/p>\n\n\n\n<p>Another common mistake is forgetting to use one of the operators when it is needed. A good practice here is to always look into your warnings while compiling your code.<\/p>\n\n\n\n<h3 class=\"wp-block-heading level_2\" id=\"24_Memory_and_memory_fragmentation\">Memory and memory fragmentation<\/h3>\n\n\n\n<p>To conclude, these are special ones, maybe more related to dynamic allocation than to pointers but I will mention them anyway.<\/p>\n\n\n\n<p>A <strong>memory leak<\/strong> occurs when a program allocates memory dynamically but fails to properly deallocate it when it is no longer needed. This can lead to reduced performance, as the system must continuously allocate blocks of memory to keep up with the demands of the program.<\/p>\n\n\n\n<p>In addition, if a program has a large number of memory leaks, it can eventually run out of memory, which can cause the program to crash. To avoid these issues, it is important to carefully manage the allocation and deallocation of memory in a program and to make sure to free memory when it is no longer needed.<\/p>\n\n\n\n<p><strong>Memory fragmentation<\/strong> occurs when the blocks of memory in a computer&rsquo;s RAM are not contiguous. This can happen when a program dynamically allocates and deallocates blocks of memory. Over time, chunks of free memory are created here and there in the RAM. When the system needs to allocate memory for a new program or task, it will need to get contiguous space. If the system is limited in resources, it may happen that there is enough free memory but not enough contiguous memory to carry on the allocation.<\/p>\n\n\n\n<p>This will result in a catastrophic failure. This problem is typically solved using memory pools or memory defragmentation. This issue impacts specifically embedded systems, where having a dedicated task for memory defragmentation may suck up too many resources. For this reason, schedulers that run on these machines often rely almost completely on static allocation.<\/p>\n\n","protected":false},"excerpt":{"rendered":"<p>Pointers can be a daunting concept for those new to the C programming language, but they are a very powerful tool that can greatly improve the efficiency of your code. In this article, we will demystify pointers and explain how they work, why they are useful, and how to use them in your C programs.<\/p>\n","protected":false},"author":3,"featured_media":8197,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1289],"tags":[1292],"coauthors":[241],"class_list":["post-8177","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-advanced-concepts","tag-c-programming","lime"],"views":4515,"jetpack_featured_media_url":"https:\/\/playembedded.org\/blog\/wp-content\/uploads\/2023\/04\/Demistifying-C-pointers-PE.jpg","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/posts\/8177","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/comments?post=8177"}],"version-history":[{"count":0,"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/posts\/8177\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/media\/8197"}],"wp:attachment":[{"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/media?parent=8177"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/categories?post=8177"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/tags?post=8177"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/coauthors?post=8177"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}