<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: L Djohari</title>
    <description>The latest articles on DEV Community by L Djohari (@lwdjohari).</description>
    <link>https://dev.to/lwdjohari</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1669484%2F1847b16e-a483-42a4-a1be-86f1a4db512c.jpg</url>
      <title>DEV Community: L Djohari</title>
      <link>https://dev.to/lwdjohari</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lwdjohari"/>
    <language>en</language>
    <item>
      <title>The Guide to Safe &amp; Modern C Memory Allocation Strategy</title>
      <dc:creator>L Djohari</dc:creator>
      <pubDate>Sun, 07 Sep 2025 22:46:24 +0000</pubDate>
      <link>https://dev.to/lwdjohari/the-guide-to-safe-modern-c-memory-allocation-strategy-1akn</link>
      <guid>https://dev.to/lwdjohari/the-guide-to-safe-modern-c-memory-allocation-strategy-1akn</guid>
      <description>&lt;p&gt;C gives you power and footguns to shoot yourself in the foot if you use it wrong. &lt;br&gt;
This note standardizes &lt;strong&gt;how we allocate, initialize, copy, and free&lt;/strong&gt; memory and strings in a &lt;strong&gt;portable, safe&lt;/strong&gt; way (ISO C + small, documented helpers). &lt;br&gt;
We avoid undefined behavior (UB), platform gotchas, and “hidden” memory allocation traps.&lt;/p&gt;
&lt;h2&gt;
  
  
  0) TL;DR Rules
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Allocation ≠ Initialization.&lt;/strong&gt; Never read uninitialized memory.&lt;/li&gt;
&lt;li&gt;Prefer &lt;strong&gt;&lt;code&gt;calloc&lt;/code&gt;&lt;/strong&gt; for structs; else &lt;code&gt;malloc&lt;/code&gt; &lt;strong&gt;+ explicit init&lt;/strong&gt; (&lt;code&gt;memset&lt;/code&gt; or field-wise).&lt;/li&gt;
&lt;li&gt;After &lt;strong&gt;&lt;code&gt;realloc&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;init the new tail&lt;/strong&gt; (bytes beyond old size).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Never use raw &lt;code&gt;strdup&lt;/code&gt; in our codebase.&lt;/strong&gt; Use &lt;code&gt;xstrdup&lt;/code&gt;/&lt;code&gt;xstrndup&lt;/code&gt; below.&lt;/li&gt;
&lt;li&gt;Centralize lifetime with &lt;strong&gt;create/destroy&lt;/strong&gt; APIs. Document &lt;strong&gt;ownership&lt;/strong&gt; (borrowed vs owned).&lt;/li&gt;
&lt;li&gt;After &lt;code&gt;free&lt;/code&gt;, &lt;strong&gt;set pointer to NULL&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  1) Core Allocation APIs
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Initialized?&lt;/th&gt;
&lt;th&gt;Must Init?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;malloc(n)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Allocate &lt;code&gt;n&lt;/code&gt; bytes (heap)&lt;/td&gt;
&lt;td&gt;❌ garbage&lt;/td&gt;
&lt;td&gt;✅ memset or assign&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;calloc(c,n)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Allocate &lt;code&gt;c*n&lt;/code&gt; bytes (heap)&lt;/td&gt;
&lt;td&gt;✅ zeroed&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;realloc(p,n)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Resize block &lt;code&gt;p&lt;/code&gt; to &lt;code&gt;n&lt;/code&gt; bytes&lt;/td&gt;
&lt;td&gt;🔸 partial¹&lt;/td&gt;
&lt;td&gt;✅ init new tail&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;alloca(n)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Allocate &lt;code&gt;n&lt;/code&gt; bytes (stack, auto free)&lt;/td&gt;
&lt;td&gt;❌ garbage&lt;/td&gt;
&lt;td&gt;✅ memset or assign&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;¹ &lt;code&gt;realloc&lt;/code&gt;: preserves old bytes; &lt;strong&gt;new bytes are uninitialized&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Golden rule:&lt;/strong&gt; &lt;em&gt;Never evaluate memory you didn’t initialize.&lt;/em&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  2) Safe Allocation Wrappers (ISO C, OOM-fatal, OOM-NULL with *_try variants)
&lt;/h2&gt;

&lt;p&gt;Use these consistent behavior:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#ifndef SAFE_ALLOC_H
#define SAFE_ALLOC_H
&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;string.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;limits.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="cm"&gt;/* Abort-on-OOM (Out of Memory) policy (common for daemons/servers).
   If you need non-fatal OOM, use *_try variants separately. */&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;xmalloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"FATAL: malloc(%zu) failed&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;abort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;xmalloc_try&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;xcalloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;nmemb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/* basic overflow guard */&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;nmemb&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;SIZE_MAX&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"FATAL: calloc overflow (%zu,%zu)&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nmemb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;abort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nmemb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;nmemb&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"FATAL: calloc(%zu,%zu) failed&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nmemb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;abort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;xcalloc_try&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;nmemb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/* basic overflow guard */&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;nmemb&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;SIZE_MAX&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nmemb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;nmemb&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;xrealloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;realloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"FATAL: realloc(%p,%zu) failed&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;abort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;xrealloc_try&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;realloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/* Free + NULL 
*  We put scope in here to avoid dangling if-else on non braces statement
*/&lt;/span&gt;
&lt;span class="cp"&gt;#define xfree(p) { if ((p) != NULL) { free(p); p = NULL; } }
&lt;/span&gt;
&lt;span class="cm"&gt;/* Bounded str duplicate: must provide valid cstr with NUL-terminate. */&lt;/span&gt;
&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;xstrdup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="cm"&gt;/* Define our policy: duplicate NULL → empty string */&lt;/span&gt;
        &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xmalloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sc"&gt;'\0'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;strlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="cm"&gt;/* +1 checked overflow */&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;SIZE_MAX&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"FATAL: xstrdup overflow&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;abort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xmalloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;memcpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="cm"&gt;/* includes '\0' */&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/* Bounded str duplicate: copy at most n bytes, n is size-1 (withouth NUL-terminate). */&lt;/span&gt;
&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;xstrndup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xmalloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sc"&gt;'\0'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;strnlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;maxlen&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;SIZE_MAX&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"FATAL: xstrndup overflow&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;abort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xmalloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="n"&gt;memcpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sc"&gt;'\0'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/* Binary memcopy helper. */&lt;/span&gt;
&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;xmemcpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xmalloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; 
        &lt;span class="n"&gt;memcpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cp"&gt;#endif &lt;/span&gt;&lt;span class="cm"&gt;/* SAFE_ALLOC_H */&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why not use &lt;code&gt;strdup&lt;/code&gt; directly?&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Our &lt;code&gt;xstrdup&lt;/code&gt; checks for overflow and defines behavior for NULL input. &lt;/li&gt;
&lt;li&gt;No surprises and consistent with our OOM policy.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3) Initialization Patterns
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Structs (configs/contexts)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;         &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;         &lt;span class="n"&gt;backlog&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt;       &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;user_data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;server_config_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/* Prefer calloc for zero/NULL defaults */&lt;/span&gt;
&lt;span class="n"&gt;server_config_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xcalloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xstrdup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"0.0.0.0"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;9000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;backlog&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/* Or: malloc + memset + field init */&lt;/span&gt;
&lt;span class="n"&gt;server_config_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;cfg2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xmalloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;cfg2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;memset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cfg2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;cfg2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;cfg2&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;9000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;xfree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;xfree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;xfree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cfg2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;realloc&lt;/code&gt; tail must be initialized
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;old_cap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_cap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xmalloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;old_cap&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="cm"&gt;/* ...write up to old_cap... */&lt;/span&gt;

&lt;span class="n"&gt;buf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xrealloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_cap&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="cm"&gt;/* New region [old_cap, new_cap) is garbage → initialize if you will read it */&lt;/span&gt;
&lt;span class="n"&gt;memset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;old_cap&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_cap&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;old_cap&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  4) Ownership Conventions (VERY IMPORTANT)
&lt;/h2&gt;

&lt;p&gt;Define clearly &lt;strong&gt;who allocates, who frees&lt;/strong&gt;. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Borrowed pointer&lt;/strong&gt;: points to memory we &lt;strong&gt;do not free&lt;/strong&gt; (e.g., literals, caller-owned). &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Owned pointer&lt;/strong&gt;: allocated here, must be &lt;strong&gt;freed&lt;/strong&gt; in destroy. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Copy-on-set&lt;/strong&gt;: safest—API duplicates input and manages it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example API
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="n"&gt;server_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;server_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;server_create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt;      &lt;span class="nf"&gt;server_destroy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;server_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;        &lt;span class="nf"&gt;server_set_host&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;server_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="cm"&gt;/* copies */&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;server_get_host&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;server_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;             &lt;span class="cm"&gt;/* borrowed */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;char&lt;/span&gt;  &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="cm"&gt;/* owned */&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;    &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;backlog&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="n"&gt;server_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;server_create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;server_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xcalloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;server_t&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;9000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;backlog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;server_set_host&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;server_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;copy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xstrdup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="cm"&gt;/* safe */&lt;/span&gt;
    &lt;span class="n"&gt;xfree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;server_get_host&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;server_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;server_destroy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;server_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;xfree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;xfree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  5) Create/Destroy + Heap Initialization
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;         &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;         &lt;span class="n"&gt;backlog&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;size_t&lt;/span&gt;      &lt;span class="n"&gt;read_chunk&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;uvsvr_config_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;uvsvr_config_t&lt;/span&gt; &lt;span class="nf"&gt;uvsvr_config_defaults&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uvsvr_config_t&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="cm"&gt;/* AS MOST C Library API always stated if char *p must be allocated, not literal*/&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xstrdup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"0.0.0.0"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;9000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;backlog&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read_chunk&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;uvsvr_config_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;uvsvr_config_new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;uvsvr_config_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xmalloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;uvsvr_config_defaults&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  6) Anti-Patterns (Don’t Do These)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Reading before init:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;  &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xmalloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;flag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* UB */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Assuming &lt;code&gt;realloc&lt;/code&gt; clears new bytes. &lt;/li&gt;
&lt;li&gt;Freeing borrowed pointers, or leaking owned ones. &lt;/li&gt;
&lt;li&gt;Using &lt;code&gt;alloca&lt;/code&gt; for large/variable buffers. &lt;/li&gt;
&lt;li&gt;Using unsafe string funcs (&lt;code&gt;strcpy&lt;/code&gt;, &lt;code&gt;strcat&lt;/code&gt;, legacy &lt;code&gt;strncpy&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  7) Practical Snippets
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Safe formatting
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;snprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;"%s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* format error */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* truncated */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  8) Checklist
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Use &lt;code&gt;xcalloc&lt;/code&gt; for structs; or &lt;code&gt;xmalloc&lt;/code&gt; + &lt;code&gt;memset&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;[ ] Always init after &lt;code&gt;malloc&lt;/code&gt;/&lt;code&gt;alloca&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;[ ] After &lt;code&gt;realloc&lt;/code&gt;, init new bytes. &lt;/li&gt;
&lt;li&gt;[ ] Use &lt;code&gt;xstrdup&lt;/code&gt;/&lt;code&gt;xstrndup&lt;/code&gt; (never avoid &lt;code&gt;strdup&lt;/code&gt;). &lt;/li&gt;
&lt;li&gt;[ ] Centralize lifetime in &lt;code&gt;create/destroy&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;[ ] Define ownership in headers. &lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;xfree&lt;/code&gt; after use → pointer = NULL. &lt;/li&gt;
&lt;li&gt;[ ] Avoid &lt;code&gt;alloca&lt;/code&gt; in production servers. &lt;/li&gt;
&lt;li&gt;[ ] Prefer &lt;code&gt;snprintf&lt;/code&gt;/&lt;code&gt;memcpy&lt;/code&gt; with explicit sizes. &lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;✅ &lt;strong&gt;Summary:&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;malloc&lt;/code&gt;/&lt;code&gt;alloca&lt;/code&gt; = garbage → must init. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;calloc&lt;/code&gt; = zeroed defaults. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;realloc&lt;/code&gt; = old preserved, new garbage. &lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;safe wrappers&lt;/strong&gt; (&lt;code&gt;xmalloc&lt;/code&gt;, &lt;code&gt;xcalloc&lt;/code&gt;, &lt;code&gt;xrealloc&lt;/code&gt;, &lt;code&gt;xstrdup&lt;/code&gt;, etc.). &lt;/li&gt;
&lt;li&gt;Centralize allocation in &lt;strong&gt;create/destroy APIs&lt;/strong&gt;. &lt;/li&gt;
&lt;li&gt;Document the &lt;strong&gt;ownership contracts&lt;/strong&gt;. &lt;/li&gt;
&lt;li&gt;This avoids UB, leaks, dangling pointers, and footguns/shooting yourself in the foot. &lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>c</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>The Guide into Strings in C for Dev who wanted to learns C - Clear Rules, Mutation, Reassignment &amp; Ownership, No Surprises</title>
      <dc:creator>L Djohari</dc:creator>
      <pubDate>Sun, 07 Sep 2025 18:40:52 +0000</pubDate>
      <link>https://dev.to/lwdjohari/strings-in-c-clear-rules-mutation-reassignment-ownership-no-surprises-2b66</link>
      <guid>https://dev.to/lwdjohari/strings-in-c-clear-rules-mutation-reassignment-ownership-no-surprises-2b66</guid>
      <description>&lt;p&gt;C++ has &lt;code&gt;std::string&lt;/code&gt; with RAII, move semantics, and safe copying. &lt;br&gt;
C has only &lt;strong&gt;pointers&lt;/strong&gt; and &lt;strong&gt;arrays&lt;/strong&gt;. You are responsible for &lt;strong&gt;allocation, mutation, reassignment, and freeing&lt;/strong&gt;.  &lt;strong&gt;You own lifetime and memory.&lt;/strong&gt; &lt;br&gt;
That’s where most bugs and shot in the foot happen in C.&lt;/p&gt;

&lt;p&gt;This guide is for C++ or migrated from any languages who want &lt;strong&gt;safe, modern C string rules&lt;/strong&gt; without ambiguity and no surprises.&lt;/p&gt;


&lt;h2&gt;
  
  
  1. The Three Faces of Strings
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Form&lt;/th&gt;
&lt;th&gt;Storage&lt;/th&gt;
&lt;th&gt;Can change contents?&lt;/th&gt;
&lt;th&gt;Can reassign pointer?&lt;/th&gt;
&lt;th&gt;Need &lt;code&gt;free&lt;/code&gt;?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;const char *p = "abc";&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;literal&lt;/td&gt;
&lt;td&gt;❌ (read-only)&lt;/td&gt;
&lt;td&gt;✅ yes&lt;/td&gt;
&lt;td&gt;❌ no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;char buf[16] = "abc";&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;array&lt;/td&gt;
&lt;td&gt;✅ (in place)&lt;/td&gt;
&lt;td&gt;❌ (arrays not assignable)&lt;/td&gt;
&lt;td&gt;❌ no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;char *p = xstrdup("abc");&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;heap&lt;/td&gt;
&lt;td&gt;✅ (if capacity fits)&lt;/td&gt;
&lt;td&gt;✅ yes&lt;/td&gt;
&lt;td&gt;✅ yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;p&gt;➡️ &lt;strong&gt;Rules of thumb:&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Literal:&lt;/strong&gt; borrowed, immutable, lives forever. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Array:&lt;/strong&gt; embedded, mutable, no free. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Heap pointer:&lt;/strong&gt; owned, mutable, must free.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;char *p&lt;/strong&gt;: In most C API DO NOT ASSIGN STRING LITERAL if you found field &lt;code&gt;char* p&lt;/code&gt; as this is marked as UB. &lt;/li&gt;
&lt;li&gt;Use C library like &lt;code&gt;sds&lt;/code&gt; if you don't want to handle string manually.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  2. Null Terminators
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Literals&lt;/strong&gt;: always null-terminated. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Arrays&lt;/strong&gt;: must have room for &lt;code&gt;\0&lt;/code&gt; . &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Heap strings&lt;/strong&gt;: always allocate +1 for terminator. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ Always use &lt;code&gt;snprintf&lt;/code&gt; for bounded, safe writes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="n"&gt;snprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"%s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"127.0.0.1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// auto NUL&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. Do You Need to &lt;code&gt;free&lt;/code&gt; Before Changing?
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Case&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Free first?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Array &lt;code&gt;char buf[N]&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;overwrite in place&lt;/td&gt;
&lt;td&gt;❌ never&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pointer → literal/borrowed&lt;/td&gt;
&lt;td&gt;reassign pointer&lt;/td&gt;
&lt;td&gt;❌ never&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pointer → heap (owned)&lt;/td&gt;
&lt;td&gt;overwrite (fits cap)&lt;/td&gt;
&lt;td&gt;❌ no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pointer → heap (owned)&lt;/td&gt;
&lt;td&gt;replace (new alloc)&lt;/td&gt;
&lt;td&gt;✅ yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;➡️ &lt;strong&gt;If unsure about capacity&lt;/strong&gt; → safest is always:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xstrdup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  4. Helper functions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  xstrdup (unbounded-length)
&lt;/h3&gt;

&lt;p&gt;Note: &lt;code&gt;xstrdup(str)&lt;/code&gt;  is my custom function to handle &lt;strong&gt;copy-on-set&lt;/strong&gt; when size is unknown. You must ensured if string is valid c-string with &lt;code&gt;\0&lt;/code&gt; terminator, otherwise it is an UB.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;string.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;errno.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="cm"&gt;/* C-string duplicate:
   - s == NULL -&amp;gt; returns owned "".
   - MUST BE VALID c-string with \0 terminated (caller’s contract).
*/&lt;/span&gt;
&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;xstrdup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
        &lt;span class="p"&gt;}&lt;/span&gt; 
        &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sc"&gt;'\0'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;strlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; 
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;memcpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  xstrndup (bounded-length)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;string.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;limits.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="cm"&gt;/* Policy: NULL or maxlen==0 -&amp;gt; return an owned empty string */&lt;/span&gt;
&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;xstrndup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;maxlen&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;maxlen&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sc"&gt;'\0'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="cm"&gt;/* Guard (maxlen + 1) overflow */&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maxlen&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;SIZE_MAX&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;strnlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;maxlen&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;memcpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sc"&gt;'\0'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  5. Practical Cases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  A) Pointer to literal (DO NOT USE)
&lt;/h3&gt;

&lt;p&gt;This pattern you &lt;strong&gt;must avoid&lt;/strong&gt;. As per most C API Contract are not allowed this pattern because it will introduce confusion when freeing the memory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.0.0.0"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c1"&gt;// borrowed literal&lt;/span&gt;
&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"127.0.0.1"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;        &lt;span class="c1"&gt;// ✅ reassign to another literal&lt;/span&gt;
&lt;span class="c1"&gt;// p[0] = '1';          // ❌ UB: can't modify literal&lt;/span&gt;
&lt;span class="c1"&gt;// free(p);             // ❌ UB: don't free literals&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  B) Literal first, then reassigned to owned copy
&lt;/h3&gt;

&lt;p&gt;This pattern must be to avoid declaring &lt;code&gt;char *p&lt;/code&gt; with literal string at first place, but it is safe.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.0.0.0"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c1"&gt;// starts as borrowed literal&lt;/span&gt;
&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xstrdup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// ✅ now heap-owned, must free later&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// ✅ now heap-owned, must free late&lt;/span&gt;
    &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key point:&lt;/strong&gt; after reassignment, ownership changes → now you mus t manage lifetime.&lt;/p&gt;

&lt;h3&gt;
  
  
  C) Array inside struct
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;S&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="n"&gt;snprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;"%s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"0.0.0.0"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;snprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;"%s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"127.0.0.1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// ✅ overwrite in place&lt;/span&gt;
&lt;span class="c1"&gt;// never free, buffer belongs to struct&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  D) Owned pointer inside struct (copy-on-set)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;S&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xstrdup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"0.0.0.0"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xstrdup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"127.0.0.1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  E) Owned pointer (mutate in place with capacity)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;snprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"%s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"0.0.0.0"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;snprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"%s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"127.0.0.1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// ✅ fits&lt;/span&gt;
&lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  F) Start as literal, then copy, then replace
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"init"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;          &lt;span class="c1"&gt;// literal, borrowed&lt;/span&gt;
&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xstrdup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;            &lt;span class="c1"&gt;// now owned heap copy&lt;/span&gt;
&lt;span class="n"&gt;replace_owned_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"newvalue"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// frees + assigns safely&lt;/span&gt;
&lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  6. Expanded Bug Cases to Avoid
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Bug&lt;/th&gt;
&lt;th&gt;Bad Code&lt;/th&gt;
&lt;th&gt;Fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Modify literal&lt;/td&gt;
&lt;td&gt;&lt;code&gt;char *p="abc"; p[0]='A';&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Use &lt;code&gt;char buf[]="abc";&lt;/code&gt; or &lt;code&gt;xstrdup("abc")&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Free literal&lt;/td&gt;
&lt;td&gt;&lt;code&gt;char *p="abc"; free(p);&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Never free literals&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Double free&lt;/td&gt;
&lt;td&gt;&lt;code&gt;free(p); free(p);&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use-after-free&lt;/td&gt;
&lt;td&gt;&lt;code&gt;free(p); p = NULL;  printf("%s", p);&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Always set to NULL, check before use&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Buffer overflow&lt;/td&gt;
&lt;td&gt;&lt;code&gt;strcpy(buf,"longstring");&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Use &lt;code&gt;snprintf(buf,sizeof buf,"%s",src)&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Uninit read&lt;/td&gt;
&lt;td&gt;&lt;code&gt;char *p=malloc(16); if(p[0]=='a')...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;calloc&lt;/code&gt; or &lt;code&gt;memset&lt;/code&gt; before read&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Realloc UB&lt;/td&gt;
&lt;td&gt;&lt;code&gt;p=realloc(p,new); use(p+old..)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Always &lt;code&gt;memset&lt;/code&gt; the new region&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  7. API Pattern: Copy-on-Set
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;replace_owned_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;copy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xstrdup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;dst&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;S&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="n"&gt;replace_owned_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"0.0.0.0"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;replace_owned_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"127.0.0.1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  8. Choosing Array vs Pointer
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Array (&lt;code&gt;char field[N]&lt;/code&gt;)&lt;/strong&gt;: fixed-size protocol fields, ISO8583 Data Elements, IPv4, timestamps. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pointer (&lt;code&gt;char *field&lt;/code&gt;)&lt;/strong&gt;: unbounded input, user-provided data. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;➡️ Arrays = simpler, no &lt;code&gt;free&lt;/code&gt;. &lt;br&gt;
➡️ Pointers = flexible, but you must free or replace carefully.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. Quick Checklist
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use C library like &lt;code&gt;sds&lt;/code&gt; if you don't want to handle string manually.&lt;/li&gt;
&lt;li&gt;NOT use literal on &lt;code&gt;char* p&lt;/code&gt; to avoid confusion during &lt;code&gt;free()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Literals: reassign pointer only; no mutate/free. &lt;/li&gt;
&lt;li&gt;Arrays: mutate in place with &lt;code&gt;snprintf&lt;/code&gt;; no free. &lt;/li&gt;
&lt;li&gt;Heap-owned: mutate if fits; else free old + copy new. &lt;/li&gt;
&lt;li&gt;If unsure always &lt;code&gt;replace_owned_string&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;After &lt;code&gt;free()&lt;/code&gt; set pointer &lt;code&gt;NULL&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;Never evaluate uninitialized memory. &lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;✅ &lt;strong&gt;Summary&lt;/strong&gt;  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;As per most C API Standard, DO NOT use literal on &lt;code&gt;char* p&lt;/code&gt; to avoid confusion during &lt;code&gt;free()&lt;/code&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;char *p = "value";&lt;/code&gt; → pointer to literal (borrowed). &lt;/li&gt;
&lt;li&gt;Reassigning to another literal = fine. &lt;/li&gt;
&lt;li&gt;Reassigning to &lt;code&gt;xstrdup("...")&lt;/code&gt; = now owned → must free. &lt;/li&gt;
&lt;li&gt;Arrays are safe, fixed buffers. &lt;/li&gt;
&lt;li&gt;Heap pointers need manual lifetime control. &lt;/li&gt;
&lt;li&gt;Copy-on-set pattern keeps your code boring and safe. &lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>programming</category>
      <category>c</category>
      <category>beginners</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Series I: CMake &amp; C++17 Quick Started</title>
      <dc:creator>L Djohari</dc:creator>
      <pubDate>Sat, 30 Nov 2024 16:59:29 +0000</pubDate>
      <link>https://dev.to/lwdjohari/series-i-cmake-c17-quick-started-2jc9</link>
      <guid>https://dev.to/lwdjohari/series-i-cmake-c17-quick-started-2jc9</guid>
      <description>&lt;p&gt;Starting modern C++ development is quite a challenging journey. This series aims to demystify &lt;strong&gt;Modern C++17 Development with CMake Project&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;I'd like to thanks to my mentor back in 2004, if I didn't met my mentor back in 2004 I might be wouldn't knows best-practices on how to develop &lt;strong&gt;cross-platform C++&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;From him i got invaluable hands-on experiences to use right approaches &amp;amp; right tools for right jobs, and one of them is &lt;strong&gt;CMake&lt;/strong&gt;. &lt;/p&gt;




&lt;h3&gt;
  
  
  Series I: CMake &amp;amp; C++17 Quick Started
&lt;/h3&gt;

&lt;h4&gt;
  
  
  In this first part of the series, we will focus on:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;C++17 Key Features&lt;/li&gt;
&lt;li&gt;Understanding &lt;code&gt;CMake&lt;/code&gt; as a C++ Project Build Tool.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can skip to next series to get down to business quick.&lt;/p&gt;

&lt;h4&gt;
  
  
  In Next Series, we will cover:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Installing the &lt;strong&gt;prerequisite&lt;/strong&gt; software to develop and compile &lt;strong&gt;Modern C++17&lt;/strong&gt; with &lt;strong&gt;CMake&lt;/strong&gt; on &lt;strong&gt;Linux/WSL2 (Windows Subsystem for Linux 2)&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Integrating Visual Studio Code (VS Code) for &lt;strong&gt;CMake C++17 Project&lt;/strong&gt; Development.&lt;/li&gt;
&lt;li&gt;Writing &lt;code&gt;C++17&lt;/code&gt; application and &lt;code&gt;CMakeLists.txt&lt;/code&gt; configuration.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Fast-Tracking for Mastering C++17 Development
&lt;/h3&gt;

&lt;p&gt;These are few key-points to fast-tracking your skill to mastering C++17 Development. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The most crucial is the memory management part&lt;/strong&gt;, once you are mastering this part you can write &lt;strong&gt;safe-memory&lt;/strong&gt; code and feel comfortable with &lt;strong&gt;C++&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Understand &lt;strong&gt;CMake for C++17 Project&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Mastering &lt;strong&gt;Data Types, Value Categories and Object Management&lt;/strong&gt;—Reference, Pointer, Lvalue, Rvalue, and Move Semantic.&lt;/li&gt;
&lt;li&gt;Mastering &lt;strong&gt;RAII Principle&lt;/strong&gt; and &lt;strong&gt;Memory Management using smart-pointer&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Mastering &lt;code&gt;struct&lt;/code&gt;, &lt;code&gt;class&lt;/code&gt; and &lt;code&gt;OOP&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Mastering &lt;code&gt;INCLUDE&lt;/code&gt; and &lt;code&gt;PROJECT-STRUCTURE&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Understanding &lt;strong&gt;static lib, shared lib and executable compilation&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Why C++17
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;C++17&lt;/strong&gt;, finalized in 2017, is a significant evolution in the C++ language. Building on its legacy since 1985, it introduced key features that separate it from predecessors, focusing on productivity, safety, and modern programming needs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C++17&lt;/strong&gt; stands out for higher productivity, &lt;strong&gt;high performance without Garbage Collector (GC)&lt;/strong&gt;, combining cutting-edge features with backward compatibility, ensuring smooth transitions while enabling modern development practices.&lt;/p&gt;

&lt;h4&gt;
  
  
  Key Features of C++17
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RAII&lt;/strong&gt;: RAII (Resource Acquisition Is Initialization) is a C++ design principle where resource management (e.g., memory, file handles) is tied to object lifetime. Resources are acquired in the constructor and released in the destructor, ensuring automatic cleanup, even in case of exceptions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smart Pointers&lt;/strong&gt;: Improved management of dynamic memory with - &lt;code&gt;std::shared_ptr&lt;/code&gt;, &lt;code&gt;std::unique_ptr&lt;/code&gt;, and &lt;code&gt;std::weak_ptr&lt;/code&gt;. Say goodbye to manual memory allocation &amp;amp; de-allocation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;std::string&lt;/strong&gt;: Yes, C++ has &lt;code&gt;string&lt;/code&gt; object. With modern C++ you will be almost never touch &lt;code&gt;*char&lt;/code&gt; to handle &lt;em&gt;string&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generic Programming through Templates&lt;/strong&gt;: &lt;code&gt;Type Templates&lt;/code&gt;, &lt;code&gt;Template Specialization&lt;/code&gt;, &lt;code&gt;Variadic Templates&lt;/code&gt; and &lt;code&gt;Class Template Argument Deduction (CTAD)&lt;/code&gt; offering capabilities comparable to languages like Java, C#, Go, or Rust.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Threading Enhancements&lt;/strong&gt;: Added parallel execution and better concurrency - with standard library features.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;std::optional&lt;/strong&gt;: Represents optional values to reduce null pointer risks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;std::variant&lt;/strong&gt;: Type-safe union for storing predefined types.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;std::filesystem&lt;/strong&gt;: Cross-platform API for file system operations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parallel Algorithms&lt;/strong&gt;: Enables parallel execution policies (e.g., - &lt;code&gt;std::for_each&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;if constexpr&lt;/strong&gt;: Compile-time branching for cleaner template code. These allow more complex computations to be performed at compile-time, improving runtime performance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improved Lambda Functions&lt;/strong&gt;: Support for &lt;code&gt;*this&lt;/code&gt; capture and default arguments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fold Expressions&lt;/strong&gt;: Simplifies variadic template argument operations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;std::string_view&lt;/strong&gt;: Lightweight, non-owning string references for efficiency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Container Improvements&lt;/strong&gt;: Enhanced containers like &lt;code&gt;std::map::try_emplace&lt;/code&gt; and insertion-order guarantees.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Allocator Flexibility&lt;/strong&gt;: Easy replacement of memory allocators for optimized performance.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  CMake as a C++ Build Tool
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;CMake&lt;/strong&gt; excels as a flexible and powerful build system generator. It allows developers to define C++ projects precisely, configure compiler settings, manage dependencies, and even execute shell commands—all while generating platform-specific build files like Makefiles, Ninja, or Visual Studio projects. &lt;/p&gt;

&lt;p&gt;CMake’s adaptability has made it the go-to tool for modern C++17 development, comparable to Gradle, Maven, or Xcodebuild in other ecosystems.&lt;/p&gt;




&lt;h3&gt;
  
  
  What is CMake?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;CMake&lt;/strong&gt; enables developers to define every aspect of a &lt;strong&gt;C++ project&lt;/strong&gt;, from build targets and compiler options to testing and installation rules. &lt;/p&gt;

&lt;p&gt;It generates build files for tools like  Ninja, abstracting platform-specific complexities.&lt;/p&gt;

&lt;h3&gt;
  
  
  History
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Origins (2000)&lt;/strong&gt;: Created by Kitware to support scientific projects like ITK and VTK.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adoption&lt;/strong&gt;: Quickly gained traction in open-source and enterprise projects for multi-platform support.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modern Usage&lt;/strong&gt;: Used by major projects like LLVM, KDE, Qt, Google Abseil, Google gRPC, and more.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Why Use CMake?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Flexibility in Defining Projects&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Precisely configure targets, source files, and build steps using &lt;code&gt;CMakeLists.txt&lt;/code&gt;. To add nested sub-projects, simply use &lt;code&gt;add_subdirectory(&amp;lt;source-folder&amp;gt; &amp;lt;build-dir&amp;gt;)&lt;/code&gt;. The &lt;code&gt;CMakeLists.txt&lt;/code&gt; file serves as the entry point of the project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cross-Platform Support&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Generates build files for Linux, Windows, and macOS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Compile Flags Management&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Easily set compiler flags for standards (e.g., &lt;code&gt;-std=c++17&lt;/code&gt;), optimization, warnings, debugging, or application-specific definition flags.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Custom Shell Commands&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Run shell commands and scripts using &lt;code&gt;add_custom_command&lt;/code&gt; or &lt;code&gt;execute_process&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dependency Management&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Seamlessly integrates libraries using &lt;code&gt;find_package&lt;/code&gt;, &lt;code&gt;FetchContent&lt;/code&gt;, or by adding the source folder with &lt;code&gt;add_subdirectory&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;IDE Integration&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Works flawlessly with IDEs like Visual Studio, Visual Studio Code, Xcode, CLion, and Eclipse.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Testing and Installation&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Built-in support for test frameworks (via &lt;code&gt;CTest&lt;/code&gt;) and installation processes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Modern C++ Features&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Leverages features like C++11/14/17/20, LTO, and sanitizers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Extensibility &amp;amp; Reusability&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Highly customizable with user-defined macros, variables, functions, and modules without get knocking-hard with complexity like another build tools.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Equivalent Tools in Other Ecosystems
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Java&lt;/strong&gt;: Gradle, Maven.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Android&lt;/strong&gt;: Gradle (Android Plugin).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;iOS/macOS&lt;/strong&gt;: Xcodebuild, Swift Package Manager (SPM).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rust&lt;/strong&gt;: Cargo.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Python&lt;/strong&gt;: setuptools, pipenv.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript/Node.js&lt;/strong&gt;: npm, yarn.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;.NET&lt;/strong&gt;: MSBuild, dotnet CLI.&lt;/li&gt;
&lt;/ol&gt;




&lt;h4&gt;
  
  
  In Next Series, we will cover:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Installing the &lt;strong&gt;prerequisite&lt;/strong&gt; software to develop and compile &lt;strong&gt;Modern C++17&lt;/strong&gt; with &lt;strong&gt;CMake&lt;/strong&gt; on &lt;strong&gt;Linux/WSL2 (Windows Subsystem for Linux 2)&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Integrating Visual Studio Code (VS Code) for &lt;strong&gt;CMake C++17 Project&lt;/strong&gt; Development.&lt;/li&gt;
&lt;li&gt;Writing &lt;code&gt;C++17&lt;/code&gt; application and &lt;code&gt;CMakeLists.txt&lt;/code&gt; configuration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See you on next series =)&lt;/p&gt;

</description>
      <category>programming</category>
      <category>cpp</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Configure Multi-Repository Git Submodules with Push via Git SSH &amp; Pull via HTTPS in Github</title>
      <dc:creator>L Djohari</dc:creator>
      <pubDate>Sat, 30 Nov 2024 14:51:21 +0000</pubDate>
      <link>https://dev.to/lwdjohari/configuring-git-multi-repository-setup-with-submodules-write-access-via-git-ssh-read-only-via-4mg2</link>
      <guid>https://dev.to/lwdjohari/configuring-git-multi-repository-setup-with-submodules-write-access-via-git-ssh-read-only-via-4mg2</guid>
      <description>&lt;p&gt;Managing multiple repositories in Git, especially when using submodules, can be tricky—especially when you want different access levels for different users. &lt;/p&gt;

&lt;p&gt;This article walks you through how to configure a Git multi-repository setup with submodules, ensuring that some users can have &lt;strong&gt;read-only&lt;/strong&gt; access to the &lt;strong&gt;submodules via HTTPS&lt;/strong&gt;, while your teams with correct credentials using &lt;strong&gt;git SSH&lt;/strong&gt; can &lt;strong&gt;push changes&lt;/strong&gt; via &lt;strong&gt;SSH&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Scenario Overview&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Imagine you have a main repository (&lt;code&gt;project&lt;/code&gt;) with two submodules (&lt;code&gt;core&lt;/code&gt; and &lt;code&gt;server&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  project &lt;span class="c"&gt;#(https://github.com/&amp;lt;your-git-user&amp;gt;/project)&lt;/span&gt;
    libs/core &lt;span class="c"&gt;#(https://github.com/&amp;lt;your-git-user&amp;gt;/core)&lt;/span&gt;
    libs/server &lt;span class="c"&gt;#(https://github.com/&amp;lt;your-git-user&amp;gt;/server)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This workflow scenario only working if your repository and its submodules is public repository.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The goal is:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Public users&lt;/strong&gt;: Can &lt;strong&gt;clone the repository and its submodules via HTTPS&lt;/strong&gt; (read-only access).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authorized users&lt;/strong&gt;: Can &lt;strong&gt;push changes&lt;/strong&gt; to &lt;strong&gt;submodules via SSH&lt;/strong&gt;, while not affecting public access.&lt;/li&gt;
&lt;li&gt;This &lt;strong&gt;workflow&lt;/strong&gt; is also apply to other &lt;strong&gt;git service provider&lt;/strong&gt; such as gitlab or bitbucket.&lt;/li&gt;
&lt;li&gt;With this workflow, everyone in your team could have different &lt;strong&gt;SSH Key Aliases&lt;/strong&gt; and &lt;strong&gt;will not impacted git repository configurations&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Through this tutorial we are use &lt;strong&gt;git SSH Aliases&lt;/strong&gt; for managing &lt;strong&gt;multi-account git SSH&lt;/strong&gt;, if you still figure it you can read quick article &lt;a href="https://dev.to/lwdjohari/configure-git-with-multi-account-ssh-and-verified-commits-using-gpg-in-github-m0c"&gt;Configure Git with Multi-Account SSH and Verified Commits Using GPG in Github&lt;/a&gt; in here.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Steps to Add Submodules to Main Repository (project)&lt;/strong&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Clone your Main Repository using Git SSH
&lt;/h4&gt;

&lt;p&gt;Make sure you have configured your &lt;strong&gt;git SSH Key Aliases&lt;/strong&gt; in your workstation and add &lt;strong&gt;SSH Key&lt;/strong&gt; to your github account.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone git@github.com-&amp;lt;your-git-user&amp;gt;:&amp;lt;your-git-user&amp;gt;/project.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. Configure Local Git Repository Config
&lt;/h4&gt;

&lt;p&gt;Configure local repository config from inside the local main repository folder (&lt;code&gt;project&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;project
git config user.name &lt;span class="s2"&gt;"Your Name"&lt;/span&gt;
git config user.email &lt;span class="s2"&gt;"your_email@example.com"&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you use commit GPG Signing you can add below configs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config user.signingkey &amp;lt;GPG_KEY_ID&amp;gt;
git config commit.gpgsign &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Add submodules to your Main Repository using HTTPS
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git submodule add https://github.com/&amp;lt;your-git-user&amp;gt;/core.git libs/core
git submodule add https://github.com/&amp;lt;your-git-user&amp;gt;/server.git libs/server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Initialize submodules and its dependencies if any&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git submodule update &lt;span class="nt"&gt;--init&lt;/span&gt; &lt;span class="nt"&gt;--recursive&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are halfway to finished this configuration, now we have to configure the &lt;code&gt;push origin&lt;/code&gt; to use &lt;strong&gt;git SSH url&lt;/strong&gt; for each submodule, users with &lt;strong&gt;Authorized git SSH Key&lt;/strong&gt; can &lt;strong&gt;push changes to submodules&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Steps to Configure &lt;code&gt;push origin&lt;/code&gt; Url for git Submodule Push Access&lt;/strong&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. &lt;strong&gt;Get Current &lt;code&gt;pull&lt;/code&gt; and &lt;code&gt;push&lt;/code&gt; Origin Url From Submodules&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;For authorized users with SSH access, set the &lt;code&gt;push origin&lt;/code&gt; for each submodule to use SSH. This ensures that pushes to submodules are done via SSH, while clones remain accessible via HTTPS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git submodule foreach &lt;span class="s1"&gt;'git remote -v 
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;output&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git submodule foreach &lt;span class="s1"&gt;'git remote -v'&lt;/span&gt;
Entering &lt;span class="s1"&gt;'libs/core'&lt;/span&gt;
origin  https://github.com/&amp;lt;your-git-user&amp;gt;/core.git &lt;span class="o"&gt;(&lt;/span&gt;fetch&lt;span class="o"&gt;)&lt;/span&gt;
origin  https://github.com/&amp;lt;your-git-user&amp;gt;/core.git &lt;span class="o"&gt;(&lt;/span&gt;push&lt;span class="o"&gt;)&lt;/span&gt;
Entering &lt;span class="s1"&gt;'libs/server'&lt;/span&gt;
origin  https://github.com/&amp;lt;your-git-user&amp;gt;/server.git &lt;span class="o"&gt;(&lt;/span&gt;fetch&lt;span class="o"&gt;)&lt;/span&gt;
origin  https://github.com/&amp;lt;your-git-user&amp;gt;/server.git &lt;span class="o"&gt;(&lt;/span&gt;push&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will print your &lt;code&gt;pull&lt;/code&gt; and &lt;code&gt;push&lt;/code&gt; url, we will configuring &lt;code&gt;push&lt;/code&gt; url to use &lt;strong&gt;git SSH url&lt;/strong&gt;.&lt;/p&gt;




&lt;h4&gt;
  
  
  2. &lt;strong&gt;Configure Submodules for Push Access (SSH)&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;For each submodule (&lt;code&gt;core&lt;/code&gt;, &lt;code&gt;server&lt;/code&gt;) we have to configure &lt;code&gt;push origin&lt;/code&gt; url&lt;/p&gt;

&lt;h4&gt;
  
  
  A. Configure Submodule &lt;code&gt;libs/core&lt;/code&gt; Push Url
&lt;/h4&gt;

&lt;p&gt;Go to submodule &lt;code&gt;libs/core&lt;/code&gt; from &lt;code&gt;project&lt;/code&gt; folder&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;libs/core
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change &lt;code&gt;push&lt;/code&gt; url to &lt;code&gt;core&lt;/code&gt; git SSH url&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git remote set-url &lt;span class="nt"&gt;--push&lt;/span&gt; origin git@github.com-&amp;lt;your-git-user&amp;gt;:&amp;lt;your-git-user&amp;gt;/core.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Configure git username, email and commit GPG signing from inside &lt;code&gt;libs/core&lt;/code&gt; folder
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config user.name &lt;span class="s2"&gt;"Your Name"&lt;/span&gt;
git config user.email &lt;span class="s2"&gt;"your_email@example.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you use commit GPG Signing you can add below configs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config user.signingkey &amp;lt;GPG_KEY_ID&amp;gt;
git config commit.gpgsign &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Go back to &lt;code&gt;project&lt;/code&gt; folder
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ../..
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now your submodule &lt;code&gt;libs/core&lt;/code&gt; will have &lt;code&gt;push origin&lt;/code&gt; point to &lt;strong&gt;git SSH&lt;/strong&gt; url.&lt;/p&gt;




&lt;h4&gt;
  
  
  B. Configure Submodule &lt;code&gt;libs/server&lt;/code&gt; Push Url
&lt;/h4&gt;

&lt;p&gt;Go to submodule &lt;code&gt;libs/server&lt;/code&gt; from &lt;code&gt;project&lt;/code&gt; folder&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;libs/server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change &lt;code&gt;push&lt;/code&gt; url to &lt;code&gt;server&lt;/code&gt; git SSH url&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git remote set-url &lt;span class="nt"&gt;--push&lt;/span&gt; origin git@github.com-&amp;lt;your-git-user&amp;gt;:&amp;lt;your-git-user&amp;gt;/server.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Configure git username, email and commit GPG signing from inside &lt;code&gt;libs/server&lt;/code&gt; folder
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config user.name &lt;span class="s2"&gt;"Your Name"&lt;/span&gt;
git config user.email &lt;span class="s2"&gt;"your_email@example.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you use commit GPG Signing you can add below configs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config user.signingkey &amp;lt;GPG_KEY_ID&amp;gt;
git config commit.gpgsign &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Go back to &lt;code&gt;project&lt;/code&gt; folder
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ../..
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now your submodule &lt;code&gt;libs/server&lt;/code&gt; will have &lt;code&gt;push origin&lt;/code&gt; point to &lt;strong&gt;git SSH&lt;/strong&gt; url.&lt;/p&gt;




&lt;h4&gt;
  
  
  2. &lt;strong&gt;Verified if &lt;code&gt;push origin&lt;/code&gt; url is Using Correct git SSH Url&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;In &lt;code&gt;project&lt;/code&gt; folder execute&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git submodule foreach &lt;span class="s1"&gt;'git remote -v'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will print your submodules &lt;code&gt;push origin&lt;/code&gt; url to point to &lt;strong&gt;git SSH url&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git submodule foreach &lt;span class="s1"&gt;'git remote -v'&lt;/span&gt;
Entering &lt;span class="s1"&gt;'libs/core'&lt;/span&gt;
origin  https://github.com/&amp;lt;your-git-user&amp;gt;/core.git &lt;span class="o"&gt;(&lt;/span&gt;fetch&lt;span class="o"&gt;)&lt;/span&gt;
origin  git@github.com-&amp;lt;your-git-user&amp;gt;:&amp;lt;your-git-user&amp;gt;/core.git &lt;span class="o"&gt;(&lt;/span&gt;push&lt;span class="o"&gt;)&lt;/span&gt;
Entering &lt;span class="s1"&gt;'libs/server'&lt;/span&gt;
origin  https://github.com/&amp;lt;your-git-user&amp;gt;/server.git &lt;span class="o"&gt;(&lt;/span&gt;fetch&lt;span class="o"&gt;)&lt;/span&gt;
origin  git@github.com-&amp;lt;your-git-user&amp;gt;:&amp;lt;your-git-user&amp;gt;/server.git &lt;span class="o"&gt;(&lt;/span&gt;push&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;.gitmodules&lt;/code&gt; file should still use HTTPS URLs for cloning. This way, public users can easily clone the repositories:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[submodule "core"]
    path = core
    url = https://github.com/&amp;lt;your-git-user&amp;gt;/core.git
[submodule "server"]
    path = server
    url = https://github.com/&amp;lt;your-git-user&amp;gt;/server.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  3. &lt;strong&gt;Push Changes from the Main Repository&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;After making changes to the main repository or it submodules, push everything as usual when we do push.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Read-Only Access for Public Users&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Users who do not have SSH credentials can still clone the repository and submodules via HTTPS&lt;/strong&gt;, but they won't be able to push any changes.&lt;br&gt;
They must push changes via &lt;code&gt;Pull Request&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Write Access for Authorized Users&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Authorized users with &lt;code&gt;SSH keys&lt;/code&gt; configured in GitHub can &lt;strong&gt;push changes directly to the submodules via SSH&lt;/strong&gt;, while other users retain &lt;strong&gt;read-only access via HTTPS&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Working &amp;amp; Push Changes to Submodules from Main Repository&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;With this workflow, you can focus working inside &lt;strong&gt;Main Repository&lt;/strong&gt; (&lt;code&gt;project&lt;/code&gt;) to made necessary changes and &lt;strong&gt;push changes&lt;/strong&gt; without struggling.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Boost Productivity with GitLens&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This is not paid sponsor, but I found from my experience during development &lt;strong&gt;GitLens&lt;/strong&gt; extension for Visual Studio Code helps a lot for my use cases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitLens&lt;/strong&gt; for Visual Studio Code simplifies managing multi-repos with submodules. It helps you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Track Submodule Changes&lt;/strong&gt;: View commit history and differences across both the main repos and submodules.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Easily Manage Configurations&lt;/strong&gt;: Visualize and manage SSH/HTTPS URLs for cloning and pushing right in your editor.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;GitLens&lt;/strong&gt; turns your Git workflow into a seamless, visual experience—perfect for managing submodules across multiple repositories.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>git</category>
      <category>programming</category>
    </item>
    <item>
      <title>Configure Git with Multi-Account SSH and Verified Commits Using GPG in Github</title>
      <dc:creator>L Djohari</dc:creator>
      <pubDate>Thu, 28 Nov 2024 06:56:52 +0000</pubDate>
      <link>https://dev.to/lwdjohari/configure-git-with-multi-account-ssh-and-verified-commits-using-gpg-in-github-m0c</link>
      <guid>https://dev.to/lwdjohari/configure-git-with-multi-account-ssh-and-verified-commits-using-gpg-in-github-m0c</guid>
      <description>&lt;p&gt;Throughout time in developments we faced multiple repositories with different git account/credentials. Managing multiple Git accounts and ensuring commit authenticity can be challenging. &lt;/p&gt;

&lt;p&gt;This guide simplifies the process by combining &lt;strong&gt;multi-account SSH key setup&lt;/strong&gt; with &lt;strong&gt;GPG signing&lt;/strong&gt; for secure authentication and trusted commits across your Linux, Windows, and macOS workstation.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Why It Matters&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;SSH Keys&lt;/strong&gt;: Manage multiple accounts securely with password-free access. Essential for handling separate work, personal, or client repositories without confusion.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GPG Signing&lt;/strong&gt;: Cryptographically sign commits to prove their authenticity and protect them from tampering—critical for secure, professional or enterprise collaborations.
&lt;/li&gt;
&lt;li&gt;This workflow is &lt;strong&gt;also apply to other git service provider such as gitlab or bitbucket.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Steps
&lt;/h2&gt;

&lt;p&gt;Typical steps to enabling multi-account Git SSH &amp;amp; GPG commit signing, you can check this big picture on how we enabling it.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create SSH Key in workstation for each account with distinct name.&lt;/li&gt;
&lt;li&gt;Save your SSH Public Key to github.&lt;/li&gt;
&lt;li&gt;Create gpg key and save to github.&lt;/li&gt;
&lt;li&gt;Clone using git SSH for push access to the repo.&lt;/li&gt;
&lt;li&gt;Config the local git repo folder to configure username, email account and signing commit using your gpg key.&lt;/li&gt;
&lt;li&gt;For complete details you can follow the rest of this article.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;1. Setting Up Multi-Account Git with SSH&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 1: Generate SSH Keys&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;For each Git account, generate a separate SSH key.&lt;/p&gt;

&lt;h4&gt;
  
  
  Linux/macOS:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; rsa &lt;span class="nt"&gt;-b&lt;/span&gt; 4096 &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="s2"&gt;"email@example.com"&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; ~/.ssh/id_rsa_personal
ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; rsa &lt;span class="nt"&gt;-b&lt;/span&gt; 4096 &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="s2"&gt;"client_email@example.com"&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; ~/.ssh/id_rsa_client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Windows (Git Bash):
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; rsa &lt;span class="nt"&gt;-b&lt;/span&gt; 4096 &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="s2"&gt;"email@example.com"&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; ~/ssh/id_rsa_personal
ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; rsa &lt;span class="nt"&gt;-b&lt;/span&gt; 4096 &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="s2"&gt;"client_email@example.com"&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; ~/ssh/id_rsa_client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Important notes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;During &lt;strong&gt;SSH Key Generation&lt;/strong&gt;, &lt;strong&gt;user&lt;/strong&gt; is your &lt;strong&gt;github username&lt;/strong&gt; and &lt;strong&gt;email&lt;/strong&gt; is your &lt;strong&gt;email registered for your github account&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;"&lt;a href="mailto:email@example.com"&gt;email@example.com&lt;/a&gt;" : you can change to your registered github email account.&lt;/li&gt;
&lt;li&gt;"&lt;a href="mailto:client_email@example.com"&gt;client_email@example.com&lt;/a&gt;" : you can change to your other registered github email account.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 2: Configure SSH&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Edit the SSH config file to associate each key with its GitHub account.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Linux/macOS&lt;/strong&gt;: &lt;code&gt;~/.ssh/config&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Windows&lt;/strong&gt;: &lt;code&gt;~/ssh/config&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the &lt;code&gt;config&lt;/code&gt;file doesn't exist you can create the file &lt;code&gt;config&lt;/code&gt; first then edit it using a text editor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
# Personal Account
Host github-personal
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_rsa_personal

# Client Account
Host github-client
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_rsa_client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;2. Adding SSH Keys to GitHub&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 1: Copy Your Public Key&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; ~/.ssh/id_rsa_personal.pub
&lt;span class="nb"&gt;cat&lt;/span&gt; ~/.ssh/id_rsa_client.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Step 2: Add Keys to GitHub&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to &lt;strong&gt;GitHub &amp;gt; Settings &amp;gt; SSH and GPG Keys &amp;gt; New SSH Key&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Paste each public key.
&lt;/li&gt;
&lt;li&gt;Label keys for clarity (e.g., "Personal" or "Client").
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 3: Clone Using SSH Aliases&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Clone repositories using the configured aliases:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone git@github-personal:username/repo.git
git clone git@github-client:client/repo.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;3. Setting Up GPG Signing&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 1: Generate a GPG Key&lt;/strong&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Linux/macOS:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpg &lt;span class="nt"&gt;--full-generate-key&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Windows (Gpg4win):
&lt;/h4&gt;

&lt;p&gt;Install &lt;a href="https://gpg4win.org/" rel="noopener noreferrer"&gt;Gpg4win&lt;/a&gt; and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpg &lt;span class="nt"&gt;--full-generate-key&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Choose &lt;code&gt;RSA and RSA (4096 bits)&lt;/code&gt; and set an expiry date.  &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 2: Export the Public Key&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Find the GPG key ID:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpg &lt;span class="nt"&gt;--list-secret-keys&lt;/span&gt; &lt;span class="nt"&gt;--keyid-format&lt;/span&gt; LONG
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Export and copy the key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpg &lt;span class="nt"&gt;--armor&lt;/span&gt; &lt;span class="nt"&gt;--export&lt;/span&gt; &amp;lt;GPG_KEY_ID&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Step 3: Add GPG Key to GitHub&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;GitHub &amp;gt; Settings &amp;gt; SSH and GPG Keys &amp;gt; New GPG Key&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Paste the public key.
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;4. Configuring Repository-Specific Settings&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;For each repository, configure local Git settings to specify the username, email, and GPG key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /path/to/repo
git config user.name &lt;span class="s2"&gt;"Your Name"&lt;/span&gt;
git config user.email &lt;span class="s2"&gt;"your_email@example.com"&lt;/span&gt;
git config user.signingkey &amp;lt;GPG_KEY_ID&amp;gt;
git config commit.gpgsign &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify settings with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--get&lt;/span&gt; user.name
git config &lt;span class="nt"&gt;--get&lt;/span&gt; user.email
git config &lt;span class="nt"&gt;--get&lt;/span&gt; user.signingkey
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures commits in the repository use the correct identity and are signed.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;5. Using and Verifying Signed Commits&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Create a Signed Commit&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git commit &lt;span class="nt"&gt;-S&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Your commit message"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Verify Signed Commits&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git log &lt;span class="nt"&gt;--show-signature&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Git will display the signature status, confirming commit authenticity.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Combining multi-account SSH key management with GPG signing ensures secure, streamlined workflows for professional developers. Whether you're managing personal, work, or client repositories, this setup keeps your Git environment organized, authenticated, and trustworthy.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>git</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
