How to change a function which returns local variable

Viewed 94

How should I change the variable BinaryNumber, so the function will not give me a warning message. I understand that I can't return a address of a local variable cause of the memory. Should I use malloc or what do you think how should I change the variable BinaryNumber so I can return it?

char *Functoin_chang_string_ToBinary(char *Line) {
    char *space = " ", *point = ",";
    char BinaryNumber[Array_Size] = { "000000000000000" };
    char *word = strtok(Line,"\"");
    int num = 0, flag = 2, j = 11;
    for (int i = 0; i < strlen(Line) - 1; i++) {
        if (word[i] == '"') {
            flag--;
            i++;
        }
        num = word[i];
        j = 14;
        while (num != 0) {
            BinaryNumber[j--] += (num % 2);
            num /= 2;
        }
        printf("%s\n", BinaryNumber);
        Fill_Struct_Binary_Machine_Code("", BinaryNumber);
        strcpy(BinaryNumber, "000000000000000");
    }
    printf("%s\n", BinaryNumber);
    Fill_Struct_Binary_Machine_Code("", BinaryNumber);

    return BinaryNumber;
}
3 Answers

Although you can use malloc() to allocate a buffer for the BinaryNumber string (which will, of course, need to be released by the caller using free()), a much simpler method would be to use the strdup() function.

This will allocate the exact amount of memory required to duplicate the string given as its argument (including the nul terminator) and copy the actual string data in one call.

Thus, you could just change your function's return statement to this:

    return strdup(BinaryNumber);

Of course, the caller will still need to call free() on the returned data when it's done with it (strdup allocates the memory in a manner compatible with the malloc function).

Change your function signature to accept a target to save it to:

char *Function_chang_string_ToBinary_r(char *Line, char *out, size_t out_size )

Whenever you do this it is far safer to provide a maximum output size as not to overrun the target. You would also use size sensitive copies for copying to the target limiting copies to the smaller of the target area our your internal working area.

Look at the strtok() vs strtok_r() function for a model for a function that switched to this model to be thread safe.

Yes, malloc() would work but I tend to consider malloc() calls within a function a bad idea, expecialy for short strings. [1] it leaves callers open to memory leaks if they forget to free the memory you allocated and [2] if the function is called frequently malloc() can have a high overhead. Passing in a NULL pointer could make the function call malloc() anyway to return the new address. This way any memory leak or performance bugs would then be on the caller.

Yes, you can return a pointer to memory allocated by malloc.

Alternatively, you could change the function prototype of Functoin_chang_string_ToBinary to the following:

void Functoin_chang_string_ToBinary(char *Line, char *BinaryNumber );

That way, the calling function can allocate the memory as a local array and pass a pointer to that array to the function Functoin_chang_string_ToBinary, for example like this:

    BinaryNumber[Array_Size];

    Functoin_chang_string_ToBinary( Line, BinaryNumber );

However, when passing pointers to memory buffers like this, it is also important to make sure that the called function does not write past the boundary of the buffer. For this reason, it would be better if the called function knew the size of the buffer it is being passed. Therefore, you may want to also pass the size of the buffer to the function, by changing the function prototype to the following:

void Functoin_chang_string_ToBinary(char *Line, char *BinaryNumber, int BinaryNumberSize )

The code of the calling function would then be changed to the following:

    BinaryNumber[Array_Size];

    Functoin_chang_string_ToBinary( Line, BinaryNumber, ArraySize );

That way, the called function can determine how large the memory buffer is, by accessing its third parameter.

Related