I am learning C in 2020 – Beginner – Understanding array memory storage

Operation System : Windows 10

IDE : VsCode

Requirements : a computer, internet, notepad

Book | Tutorial : see links below

Git Project :None


Goal

Learn how int and char arrays are stored in memory and how much memory is allocated in specific scenarios.

What I learned

Integer arrays

Pre and Post assignment

I wanted to find out if the size of a simple integer array is dependent on whether there are assigned values or not. As shown below, the options array uses 240 bytes for storage regardless of assignment.

#include <stdio.h>
#include <stdlib.h>

int main() {
 int options[60];

printf("Array length:  %li \n Array byte storage: %li \n int size : %li \n--------------\n"
,( sizeof(options) / sizeof(options[0]))
,sizeof(options), sizeof(int));
return 0;
    
}
Array length:  60 
 Array byte storage: 240 
 int size : 4 
--------------
#include <stdio.h>
#include <stdlib.h>

int main() {
 int options[60] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
printf("Array length : %li \n Array byte storage: %li \n int size : %li \n ------------ \n",
( sizeof(options) / sizeof(options[0]))
,sizeof(options), sizeof(int));
return 0;
    
}

Array length : 60 
 Array byte storage: 240 
 int size : 4 
 ------------

Does the computer allocate more space than required if the programmer never explicitly states the number of items ?

The scores array’s, although declared without an array size by the programmer ( me), is shown to be 5 times 4 bytes = 20 bytes. Seeing that there are 5 int items in the scores array, one can assume that the computer determined the needed size based on the items provided.

#include <stdio.h>
#include <stdlib.h>

int main() {
int scores[] = {11, 12,367,33,134};

printf("Array length : %li \n Array byte storage: %li \n int size : %li \n ------------ \n"
,
(  sizeof(scores) / sizeof(scores[0])  )
,sizeof(scores), sizeof(int));
return 0;
    
}
Array length : 5 
 Array byte storage: 20 
 int size : 4 
 ------------

What happens when an empty array is assigned?

Apparently the computer creates a jargon integer and calls it the first element of the array. For example the scores array has only one element ( int = 4 bytes ) despite being set to empty by the programmer.

#include <stdio.h>
#include <stdlib.h>

int main() {
int scores[] = {};

printf("Array length : %li \nArray byte storage: %li \nint size : %li \nFirst element: %i \n ------------ \n"
,
(sizeof(scores) / sizeof(scores[0]))
,sizeof(scores), sizeof(int), scores[0]);
return 0;
}

Array length : 0 
Array byte storage: 0 
int size : 4 
First element: 32767 
 ------------

What happens when the scores array is neither initialized nor given an array size ?

An error is thrown by the compiler stating hey, if you aren’t going to provide at least an empty list to throw a garbage value in, then give me a size. Simply paraphrasing…

#include <stdio.h>
#include <stdlib.h>

int main() {
int scores[];

printf("Array Length: %li \n int size : %li \n First element: %i \n ------------ \n",
sizeof(scores), sizeof(int), scores[0]);
return 0;
    
}
/cplayground/code.c: In function 'main':
/cplayground/code.c:5:5: error: array size missing in 'scores'
 int scores[];

If the array size is set but the number of items added to the array is lesser than the array size, how does the computer manage it ?

I suppose the computer prioritizes the explicitly set array size over the actual number of items provided by the programmer ( 28 / 4 = 7 not . The computer, as shown below, throws in some garbage values ( 0 ) at the “empty” spots.

#include <stdio.h>
#include <stdlib.h>

int main() {
int scores[7] = {11, 12,367,33,134,5};

printf("Array length: %li \nArray byte storage: %li \nint size : %li \nLast item: %i \n ------------ \n"
,( sizeof(scores) / sizeof(scores[0]) )
,sizeof(scores), sizeof(int), scores[6]);
return 0;
    
}

Array length: 7 
Array byte storage: 28 
int size : 4 
Last item: 0 
 ------------

Multi-dimensional Integer arrays

Does the individual storage size of each sub-array affect the overall storage size ?

Based on the example below, yes. Since there would be 2 int arrays each holding 3 integers, the total bytes required for storage will be 2 * 3 * 4 bytes = 24 bytes. This means each sub-array would be stored with 12 bytes 3 integers * 4 bytes.

#include <stdio.h>
#include <stdlib.h>

int main() {
int multi[2][3] ;

printf("Array Length: %li \nArray byte storage: %li \nint size : %li \n",
(  sizeof(multi) / sizeof(multi[0][0])  ),
sizeof(multi),
sizeof(int));
printf("Sub-array length : %li \n ------------ \n", sizeof(multi[0]));
return 0;
    
}
Array Length: 6 
Array byte storage: 24 
int size : 4 
Sub-array length : 12 
 ------------
#include <stdio.h>
#include <stdlib.h>

int main() {
int multi[2][3] = { {6, 3, 3},{1, 88, 3} } ;

printf("Array Length: %li \nArray byte storage: %li \nint size : %li \n ------------ \n"
,( sizeof(multi) / sizeof(multi[0][0]) )
,sizeof(multi), sizeof(int));
return 0;
    
}

Array Length: 6 
Array byte storage: 24 
int size : 4 
 ------------

Character arrays vs String constants

Does bytes storage for char arrays work similarly to int arrays ?

From the example shown below, since each char requires only 1 byte for storage, an array of 13 characters + a null-char “\0” would demand 14 bytes. So somewhat similar.

#include <stdio.h>
#include <stdlib.h>

int main() {
char name[] = "Comfort Ajala";

printf("Array Length: %li \nArray byte storage: %li \n  char size : %li \n ---------\n"
,
(   sizeof(name) / sizeof(name[0]) )
,
sizeof(name), sizeof(char));
return 0;
    
}
Array Length: 14 
Array byte storage: 14 
  char size : 1 
 ---------

What about char pointers pointing to char arrays living in the constant memory area ?

I read somewhere that the size for storing a pointer ( excluding an array ) does not reflect the storage bytes of the data stored at the address indicated by the pointer. We already know the variable name above holds 13 characters + 1 null character, so why does the program log 8 bytes instead of 14 bytes ? After a very brief research ( googling) it is clear that the bytes do not indicate array storage instead pointer storage.

It is still a bit confusing to me .

#include <stdio.h>
#include <stdlib.h>

int main() {
const char * name = "Comfort Ajala";

printf("Array byte storage: %li \n const char pointer size : %li \n ---------\n",
sizeof(name), sizeof(const char *));
return 0;
    
}
Array byte storage: 8 
 const char pointer size : 8 
 ---------

Multi-dimensional char arrays

This is very similar to the multi-int arrays. The texts array below holds 4 hundred character arrays. An observation is the size of each sub-array. Despite their clear difference in length, they all are of length 100. Thus the amount of bytes for storage is:

100 chars * 4 items * 1 byte = 400 bytes.
#include <stdio.h>
#include <stdlib.h>

int main() {
char texts[][100] =
{ "ply dummy text ",
  "but also the",
  "ntaining Lorem",
  "tpassages, and more "
};


printf("Array byte storage: %li \n char size : %li \n char size: %li \n ------------ \n",
sizeof(texts),sizeof(char ), sizeof(char ));
printf("Nr.%i --> %s = %li\n", 0, texts[0], sizeof(texts[0]));
printf("Nr.%i --> %s = %li\n", 1, texts[1], sizeof(texts[1]));
printf("Nr.%i --> %s = %li\n", 2, texts[2], sizeof(texts[2]));
printf("Nr.%i --> %s = %li\n", 3, texts[3], sizeof(texts[3]));
printf("----------------\n");
return 0;
    
}
Array byte storage: 400 
 char size : 1 
 char size: 1 
 ------------ 
Nr.0 --> ply dummy text  = 100
Nr.1 --> but also the = 100
Nr.2 --> ntaining Lorem = 100
Nr.3 --> tpassages, and more  = 100
----------------

Array of pointers to constant char arrays

Unlike the sub character array above, this example deals with an array holding pointers pointing to an array of characters living in the constant memory.

As expected,the size of the variable “texts” is 32 bytes not 61 bytes. This is because the size of the char pointer is 8 bytes. So 8 bytes * 4 char pointers = 32 bytes.

#include <stdio.h>
#include <stdlib.h>

int main() {
char * texts[] =
{ "ply dummy text ",
  "but also the",
  "ntaining Lorem",
  "tpassages, and more "
};


printf("Array byte storage: %li \n char size : %li \n char pointer size: %li \n ------------ \n",
sizeof(texts),sizeof(char ), sizeof(char * ));
return 0;
    
}
Array byte storage: 32 
 char size : 1 
 char pointer size: 8 
 ------------
#include <stdio.h>
#include <stdlib.h>

int main() {
const char *b[2];


printf("Array byte storage: %li \n const char pointer size: %li \n ------------ \n",
sizeof(b),sizeof(const char * ));
printf("Nr.%i --> %s = %li\n", 0, b[0], sizeof(b[0]));
printf("Nr.%i --> %s = %li\n", 1, b[1], sizeof(b[1]));
printf("----------------\n");
return 0;
    
}
Array byte storage: 16 
 const char pointer size: 8 
 ------------ 
Nr.0 --> AWAVI''AUATL'%'  = 8
Nr.1 --> 1'I''^H''H'''PTI'''@ = 8
----------------
#include <stdio.h>
#include <stdlib.h>

int main() {
char b[2][14];


printf("Array byte storage: %li \nchar size: %li \n ------------ \n",
sizeof(b),sizeof(char ));
printf("Nr.%i --> %s = %li\n", 0, b[0], sizeof(b[0]));
printf("Nr.%i --> %s = %li\n", 1, b[1], sizeof(b[1]));
printf("----------------\n");
return 0;
    
}
Array byte storage: 28 
char size: 1 
 ------------ 
Nr.0 --> ''ު= = 14
Nr.1 -->  = 14
----------------
#include <stdio.h>
#include <stdlib.h>

int main() {
char title[13] = "TonightWouldBeGreat"; 


printf("Array byte storage: %li \nchar size: %li \n ------------ \n",
sizeof(title),sizeof(char ));
printf("Nr.%i --> %c = %li\n", 0, title[0], sizeof(title[0]));
printf("Nr.%i --> %c = %li\n", 1, title[1], sizeof(title[1]));
printf("----------------\n");
return 0;
    
}
Array byte storage: 13 
char pointer size: 1 
 ------------ 
Nr.0 --> T = 1
Nr.1 --> o = 1
----------------
#include <stdio.h>
#include <stdlib.h>

int main() {
char alpa[10] = {'A','b','c','d','e','f','g','\0'};   


printf("Array byte storage: %li \nchar size: %li \n ------------ \n",
sizeof(alpa),sizeof(char ));
printf("Nr.%i --> %c = %li\n", 0, alpa[0], sizeof(alpa[0]));
printf("Nr.%i --> %c = %li\n", 1, alpa[1], sizeof(alpa[1]));
printf("----------------\n");
return 0;
    
}
Array byte storage: 10 
char size: 1 
 ------------ 
Nr.0 --> A = 1
Nr.1 --> b = 1
----------------
#include <stdio.h>
#include <stdlib.h>

int main() {
char coursename[] = "materialscience" ;


printf("Array byte storage: %li \nchar size: %li \n ------------ \n",
sizeof(coursename),sizeof(char ));
printf("Nr.%i --> %c = %li\n", 0, coursename[0], sizeof(coursename[0]));
printf("Nr.%i --> %c = %li\n", 1, coursename[1], sizeof(coursename[1]));
printf("----------------\n");
return 0;
    
}
Array byte storage: 16 
char size: 1 
 ------------ 
Nr.0 --> m = 1
Nr.1 --> a = 1
----------------

Miscellaneous Information

How are char arrays stored ?

To know further about WHERE they are stored, I urge you to visit this post.

  1. Char is converted to its ASCII value e.g. B = 66 ( See links for ASCII table )
  2. The number is then converted to binary format
  3. The binary value is stored in either a byte or 8 bits .

Links

  1. Types of Arrays in C
  2. Storage for Strings in C
  3. How character is stored in Computer
  4. ASCII Table