c++arraysmemoryc-strings

How to reduce memory used by an array buffer?


I am learning C++. I have a code which is working, but now I am wondering if it can be optimized in terms of memory usage?

I need to get and keep a few strings in a character array, but the number of strings and their lengths are not known at compile time. So I make a buffer which is extra large to hold everything, but when it is not filled then it's just a waste of memory.

#include <cstring>

char arr[20][30]; // the buffer

const char* getStr(int i) { // this not the actual getStr function
    if(i < 10){
        return "sometext";
    }else{
        return 0;
    }
}

void fillArr(){
    const char* chArr;
    for (int i = 0; i < 20; i++){
        chArr = getStr(i); // the exact output of getStr is not known beforehand
        if(chArr){
            strcpy(arr[i], chArr);
        }else{
            return;
        }
    }
}

int main() {
    fillArr();
    return 0;
}

So, the buffer takes 600 bytes, but it may need to keep only like 50 bytes (or more), so a large portion of unused memory is wasted. How can I optimize it?

I don't want to use the string class, because it is said to add a few KB to memory usage.

This is for an embedded system, so memory usage is of concern.


Solution

  • First: I am assuming you actually wanted to use C even though you have C++ tagged just because your code is C code. If it was C++ you would be using vector and string.

    Instead of making 20 characters for each entry leave them as NULL and then use strdup instead of strcpy to fill them - the only thing you need to worry about is checking if they are NULL before using them.

    https://onlinegdb.com/tszSh_etc

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    char *arr[20] = {0}; // clear the buffer to all zeros
    
    const char* getStr(int i) { // this not the actual getStr function
        if(i < 10){
            return "sometext";
        }else{
            return 0;
        }
    }
    
    void fillArr(){
        const char* chArr;
        for (int i = 0; i < 20; i++){
            chArr = getStr(i); // the exact output of getStr is not known beforehand
            if(chArr){
                arr[i] = strdup(chArr);
            }else{
                return;
            }
        }
        return;
    }
    
    void printArr() {
        for (int i = 0; i < 20; i++){
            if(arr[i]){
                printf("%i: %s\n",i,arr[i]);
            }
        }
        return;
    }
    
    void clearArr() {
        for (int i = 0; i < 20; i++){
            if(arr[i]){
                free(arr[i]);
            }
        }
        return;
    }
    
    int main() {
        fillArr();
        printArr();
        clearArr();
        return 0;
    }