Usually I develop in PHP. But for a project I have to develop a small program in C (using Visual Studio on Windows)
To simplify my code I created a function that returns a string (the function is more complex than in the example).
Initially I had a warning C4172: returning address of local variable or temporary [duplicate]
I modified my function to no longer have this warning. And it works.
But is the code right…?
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
// Declaration Function
char* getMyString();
//----------------------------//
// Function getMyString() //
//----------------------------//
char* getMyString()
{
char* response = NULL;
response = (char*)malloc(5 * sizeof(char)); if (response == NULL) exit(EXIT_FAILURE);
strcpy(response, "EFGH");
return response;
}
//--------------------------------------------------//
// Main Program //
//--------------------------------------------------//
int main(int nbArg, char** listeArg)
{
// Initialization
char* myStringFull = malloc(10 * sizeof(char)); if (myStringFull == NULL) return EXIT_FAILURE;
char* myString = NULL;
// Get String with Personnal Function
myString = getMyString();
// Finalization
strcpy(myStringFull, "ABCD");
strcat(myStringFull, myString);
// Display
printf("n%snn", myStringFull);
// Free Memory
free(myStringFull);
free(myString);
return(EXIT_SUCCESS);
}
And if above code is right, can I use the code below to further simplify my code…?
And if I can how it happens in memory because for this last code I can not free the memory used by the function
int main(int nbArg, char** listeArg)
{
// Initialization
char* myStringFull = malloc(10 * sizeof(char)); if (myStringFull == NULL) return EXIT_FAILURE;
// Finalization
strcpy(myStringFull, "ABCD");
strcat(myStringFull, getMyString());
// Display
printf("n%snn", myStringFull);
// Free Memory
free(myStringFull);
return(EXIT_SUCCESS);
}
Hope my question isn’t too silly but there is a big, huge, abyssal gap between PHP and C 🙂
3
Answers
What you did is correct. However, you’ve noticed that it’s quite a bit of work, and you have to remember to free the allocated memory afterwards. If possible, I would use C++ so you can return a
std::string
without worries, much like you would do in PHP and many other languages.There are other functions that might help you create strings in C. For example, copying strings can be done by the POSIX function
strdup()
. You can also useasprintf()
on GNU and BSD platforms.Instead of allocating memory, you could also print into a buffer. To do that from a function, you would pass a pointer to the buffer and its size to that function. For example:
Note that the above is still missing error checking; the return value of
snprintf()
is the number of characters that would have been written if the buffer was large enough, or possibly a negative number indicating an error.There are three main ways to do what you want:
static
buffer with enough space to hold the data when the function is not in useThis solution has the drawback that it is not reentrant, so if two threads try to use it at the same time, bot executions will overwrite the buffer and the result will be trashed.
malloc(3)
, and return the pointer to the allocated memory. This has the drawback that the calling routine is responsible (and must know) offree(3)
ing the memory once it’s not neede anymore.This solution makes the calling code responsible or returning the memory and so, is error prone.
This approach gives the caller the responsibility of allocating the space, and so, it doesn’t have to be dynamic, can be local space, as you pass the reference to it and its size.
You can select the one best fits you, but from my point of view the more flexible is the last one. Just try them all.
A string in C is just a sequence of characters in an array, but you can’t return an array from a function, so you can’t directly return a ‘string’.
What C functions usually do is pass the array (and size) as an argument to the function and have the function put the string in the array to "return" it. Stdlib functions like
fgets
andsnprintf
work this way; their first and second arguments are a pointer to an array and the size of that array. In your case that would be something like: