[C] Dynamic Memory (Part 2.0): Arrays on the Heap

static
array
cprogramming
heap
dynamic

(oaktree) #1

Alright. Because I like doing these and find this topic to be “okay”, difficulty-wise, I’m doing two articles in two days. This is Part 2.0, the followup to Part 1.0, which was about using malloc and free on pointers.

In this article, we’ll be using the same functions (malloc and free), but with arrays. So, oak, what’s the difference? I’m glad you asked!

Let’s walk through an example…


// ...
char* s1 = "bjldjfdjf";

char* s2 = malloc( sizeof(char) * ( strlen(s1) + 1) );
// note: we allocate for strlen(s1) + 1 because of the '\0' character present at the end of a C string.

if (!s2)
    perror("Couldn't alloc for s2");

for (int i = 0, n = strlen(s1); i < n; i++)
    s2[i] = s1[i];

s2[strlen(s1)] = '\0';

printf("s1: %s\ns2: %s\n", s1, s2);

free(s2);

// ...

Alright, so the above code is essentially pointless and does what strdup does (look it up if you’d like, but it’s irrelevant to this topic so don’t let it confuse you).

Essentially, you can declare a string in C with a string literal, which means that the string is hardcoded into your program.

s1 is declared and assigned a string literal. s2, another char * is mallocd to match the length of s1, and we proceed to copy the contents of s1 into s2.

See, you could call malloc with the parameter of just sizeof( char ) to get space for just one character. But, you can also allocate enough memory for several “units” of the relevant type.

As a followup example, to create an integer array of 5 elements on the heap, I can do:

int *arr = malloc( sizeof(int) * 5 );

This essentially gives me 5 ints worth of space. I can access each element as you would with a static array, using the subscript operator:

arr[3] = 609;

I can do whatever I want with the 5 elements I have allocated.


Now, back to that char * example… There’s one thing about strings in C that make them stand out amongst other arrays. While you could easily store a 5-character string in a 5-char memory block, you store it in a 6-char memory block instead, reserving the last element, the 6th element, for a special character. This last element holds the value '\0', the null byte, for which our former community was named.

The null byte’s role is to delimit a string. A delimiter is a symbol used to mark or note something. In this case, the null byte marks the end of the string. If you didn’t have a null byte in a C string, your program might think that that string never ends. Such would lead to what is referred to in the CS community as undefined behaviour.


Conclusion

That’s all for the second edition of this series. If any additional explanations are needed, please ask below.

Next time, we’ll get into what happens when you want to grow or shrink the array, depending on your needs.

Arrays All Day
@oaktree


[C] Dynamic Memory (Part 3.0): Dynamic Buffering
(oaktree) #2

This topic was automatically closed after 30 days. New replies are no longer allowed.