0

I am working on a custom SD card data logger using the following function and struct:

char *filenameCreator(const char *prefix, const char *num, bool addExtension)
{
    char *filename = (char *)malloc(13 * sizeof(char));
    const char *uScore = "_";
    strcpy(filename, prefix);
    strcat(filename, uScore);
    strcat(filename, num);
    if (addExtension)
    {
        const char *ext = LOGFILE_EXTENSION;
        strcat(filename, ext);
    }
    delete[] num;
    return filename;
}

where the output will be saved on a variable of the following type:

struct FileInfo
{
    const char *fileName;
    double fileSize;
};

with FileInfo fileToDelete; and a global variable char* createdFilename = nullptr; to temporarily store the function's output.

The issue is that when using the functions as follows, fileToDelete.fileName is EMPTY:

createdFilename= filenameCreator("FILE", numericConverter(receivedIndexSATCOM), true);
fileToDelete.fileName = createdFilename;

free(createdFilename);    // seems to clear the contents of the variable where the filename was stored, namely, fileToDelete.fileName
createdFilename = nullptr;

I am trying to stick to the rules of freeing up memory used by malloc'd variables.

Please note that if I DON'T USE free(createdFilename), the code works fine and the fileName is created correctly. However, I am concerned about undefined behaviour or erratic responses.

Here is an example of a filename successfully created when NOT using free():

enter image description here

Do I invariably need to free the pointer after each use? Why the contents are empty even after assigning the contents to another variable?

EDIT:

Please, instead of downvoting my question, comment on what is wrong with my questions and I will try to improve it. Be mature.

7
  • 1
    See the accepted answer here. stackoverflow.com/questions/37514873/…
    – Delta_G
    Commented May 10 at 2:31
  • 2
    dont't use dynamic memory allocation. pass a buffer on stack to the function
    – Juraj
    Commented May 10 at 4:17
  • You might want to read about the reasons to vote down. In your case your question shows no effort of research on your issue, neither in the web nor on this site. However, you are supposed to do this before asking. (Disclaimer: I did not vote down.) Commented May 10 at 5:40
  • 1
    @Juraj As a general advice, I don't agree. There are good reasons for dynamic memory allocation, even on an Arduino. It depends on the software design. Commented May 10 at 5:44
  • 1
    We just looked at your question, that's it. We cannot see what you do else, and so it does not matter to us. Your post does not show any reference how you tried to solve your issue yourself and why you failed. If you think this bloats your question, well, it helps. Otherwise you'll receive irrelevant or misleading answers, which waste more of your and our time. Commented May 10 at 12:04

1 Answer 1

3

What you have is called a "Dangling Pointer". You are trying to use a pointer that is pointing to memory that has been freed and doesn't contain what you think it does anymore.

This line of code in the filenameCreator function:

char *filename = (char *)malloc(13 * sizeof(char));

allocates a block of memory in the heap and saves a pointer to it. Later in the function you return that pointer.

return filename;

When you call this function:

createdFilename= filenameCreator("FILE", numericConverter(receivedIndexSATCOM), true);

You assign that pointer value to a new pointer. Now createdFilename points to this block of memory that you allocated in the function.

When you get to this line:

free(createdFilename);

That frees the block of memory that is being pointed to. This means that its contents can be destroyed, or left there, or used for something else. You've said with this line of code that you won't use it anymore.

If you try to use createdFilename later, it will still point to the same place in memory. But the stuff you had stored there has been freed. It is no longer there.

If it is your intention to keep using that file name, then don't free the memory until you are done using it. Sometimes that means the life of the program and you never call free.

It is important to free memory that you allocated, but only when you are done using it.

2
  • Thank you for your detailed and professional response. It makes absolute sense to me now. This "issue" is part of a massive project that has been mentally draining me and I am not thinking clearly. As it seems, not freeing up the pointer shouldn't be a problem then. Commented May 10 at 9:25
  • 1
    @DanielMelendrez If you are allocating pointer, you have to free it when it's no longer needed. Problem in your code isn't not freeing it as it's been already freed and pointer in fileToDelete.fileName is invalid
    – KIIV
    Commented May 10 at 9:48

Not the answer you're looking for? Browse other questions tagged or ask your own question.