I started learning C, and I don't understand what I'm doing wrong. Here is a simple code of a function that returns the pid+".data".
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
char * getfilename(){
char name[60];
sprintf(name,"%i.data",getpid());
return name;
}
void main(){
char* name = getfilename();
printf("%s",name);
}
outputs: ��#�a.
So I guess that I'm doing something wrong.
char * getfilename(){
char name[60];
sprintf(name,"%i.data",getpid());
return name;
}
You cannot access name object after getfilename has returned. The lifetime of the automatic object name ends at the getfilename last }. Accessing it after the function returns is undefined behavior.
As a temporary fix you can specify name as static and it will work. But what you should do is to have the getfilename function accepts a pointer argument where the filename will be written.
EDIT:
Why I don't suggest to use strdup?
strdup is not a Standard C function. strdup lives in the POSIX world. For portability reasons whenever I can, I prefer to use Standard C functions.
strdup performs a hidden malloc call and you have not to forget to perform a free. This is contrary to all functions of the Standard C library which never call malloc (or actually that never appear to call malloc). strdup is a bad API design.
strdup is performing a copy of a string. Why do you need to perform an extra copy? Just write the string in a place you can retrieve it.
One solution is to use strdup, i.e. change:
return name;
to:
return strdup(name);
This makes a copy of your temporary (local) string using dynamic memory allocation (i.e. malloc).
You must of course make sure that you subsequently free this string when you're done with it.
You'll need:
#include <string.h> // strdup()
#include <stdlib.h> // free()
char name[60]
lives on the stack, but only as long as being inside getfilename() afterwards its freed, so any references (as also returned by getfilename()) to it become invalid.
char name[60] is a local variable which is allocated when the function is called and deallocated when it returns. When you try to return it, you're really returning it's address (after all arrays are mostly syntactic sugar for pointer arithmetic). Now, your caller has a pointer to a block of memory that has been free, and thus will likely contain garbage.
You can't return the array name from your function getfilename, because it is a (regular) local variable and those get cleaned up when the function returnes.
So, when you get back in main and try to print the returned value, the pointer name there refers to a block of memory that has been reused for other purposes.
There are several solutions for this problem:
Make name in getfilename static. This will ensure that it outlives the call to getfilename and can safely be returned, but has the drawback that all calls to getfilename use the same buffer.
Allocate the array dynamically with malloc (and don't forget to clean it up with free when you are done with it)
Pass the buffer to store the value in as a parameter.
As mentioned in the other answers you cannot return a pointer which points somewhere in the stack of a function.
You can simply pass the allocated array to getfilename() function. You can rewrite the program as follows.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void getfilename(char * name)
{
sprintf(name,"%i.data",getpid());
}
int main(void)
{
char name[60];
getfilename(name);
printf("%s\n",name);
return 0;
}
This should work fine.
Related
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
char* test() {
char* s = "Hello World";
size_t len = strlen(s);
char* t = malloc(sizeof(char)*(len+1));
strcpy(t, s);
free(t);
return t;
};
int main(void) {
printf("%s\n", test());
return 0;
};
I would like to allocate and de-allocate memory inside the function. I tested this code and works, but I am wondering:
Why does this work?
Is it good practice to use the value of a freed pointer in main ?
Once you call free on a pointer, the memory it pointed to is no longer valid. Attempting to use a pointer to freed memory triggers undefined behavior. In this particular case it happened to work, but there's no guarantee of that.
If the function returns allocated memory, it is the responsibility of the caller to free it:
char* test() {
char* s = "Hello World";
size_t len = strlen(s);
char* t = malloc(sizeof(char)*(len+1));
strcpy(t, s);
return t;
};
int main(void) {
char *t = test();
printf("%s\n", t);
free(t);
return 0;
};
malloc reserves memory for use.
free releases that reservation. In general, it does not make the memory go away, it does not change the contents of that memory, and it does not alter the value of the pointer that held the address.
After free(t), the bytes of t still contain the same bit settings they did before the free. Then return t; returns those bits to the caller.
When main passes those bits to printf, printf uses them as the address to get the characters for %s. Since nothing has changed them, they are printed.
That is why you got the behavior you did with this program. However, none of it is guaranteed. Once free was called with t, the memory reservation was gone. Something else in your program could have used that memory. For example, printf might have allocated a buffer for its own internal use, and that could have used the same memory.
For the most part, malloc and free are just methods of coordinating use of memory, so that different parts of your program do not try to use the same memory at the same time for different purposes. When you only have one part of your program using allocated memory, there are no other parts of your program to interfere with that. So the lack of coordination did not cause your program to fail. If you had multiple routines in your program using allocated memory, then attempting to use memory after it has been released is more likely to encounter problems.
Additionally, once the memory has been freed, the compiler may treat a pointer to it as if it has no fixed value. The return t; statement is not required to return any particular value.
It doesn't matter where do you free() a pointer. Once it is free()d, the pointer is not deferrenciable anymore (neither inside nor ouside the function where it was free()d)
The purpose of free() is to return the memory allocated with malloc() so the semantics are that, once you have freed a chunk of memory, it is not anymore usable.
In C, all parameters are passed by value, so free() cannot change the value expression you passed to it, and this is the reason the pointer is not changed into an invalid pointer value (like NULL) but you are advised that no more uses of the pointer can be done without incurring in Undefined Behaviour.
There could be a solution in the design of free() and it is to pass the pointer variable that holds the pointer by address, and so free() would be able to turn the pointer into a NULL. But this not only takes more work to do, but free() doesn't know how many copies you have made of the value malloc() gave to you... so it is impossible to know how many references you have over there to be nullified. That approach makes it impossible to give free() the responsibility of nullifying the reference to the returned memory.
So, if you think that free doesn't turn the pointer into NULL and for some strange reason you can still use the memory returned, don't do it anymore, because you'll be making mistakes.
You are adviced! :)
I was a bit confused with the concept of char pointers so I made a simple code just printing my name provided by user (me). I also wanted to practice malloc so I referenced the pointer to a certain memory in RAM, but I really didn't know what to put after "sizeof(char) *" because that is the user input, which is not yet decided.
Also, after doing that, I freed the memory, but I got an error message on command line saying:
*** Error in `./char': double free or corruption (fasttop): 0x00000000017fe030 ***
Aborted
It seems like I freed the same memory twice or something, but I don't know what to delete or add. Please help!
#include <stdio.h>
#include <cs50.h>
int main (void)
{
char *strings = malloc(sizeof(char) * 10);
printf("What is your name?\n");
//wait for use to type his/her name
strings = get_string();
printf("Hello %s\n", strings);
free (strings);
return 0;
}
The line strings = get_string(); actually assigns the value returned by get_string() to strings. It doesn't write it into the memory you allocated.
So the value returne by malloc() has been overwritten (and lost in this case).
The free(strings) is releasing whatever get_string() returned. The question doesn't provide the code for that but presumably it isn't valid to free() it.
Because the run-time told you it was freed twice I'm guessing you have allocated memory in get_string() then freed it and returned an invalid pointer.
If you want to use the memory you allocated you need to change get_string() to accept a pointer:
void get_string(char *str){
//Do whatever writing you value into str[] as an array of char..
}
Good practice would have:
void get_string(char *str, size_t max){
//Do whatever writing you value into str[] as an array of char..
//Use max to avoid writing beyond the end of the space allocated...
}
Then call as get_string(strings,10);.
EDIT: After a bit of research the flaw has been identified. get_string() doesn't directly free() the string it returns but adds it to a list of allocations made by the library which are freed on exit (in a function called teardown() registered with atexit() or other compiler dependent features).
That is poor design because consumer code is provided no safe way of itself freeing the memory which in a typical use case will not be required for the whole application execution. get_double() is worse because it never returns the allocated data but never reuses it and amounts to a straight memory leak.
The code should either:
Conform to the documentation and require consumer code to free() the string (maybe rename it as say get_string_alloc() for clarity).
Offer a library routine to free the string (get_new_string() and release_string())
There is no very nice way to shift ownership of allocated memory in C but holding onto it for the remainder of execution is definitely not the answer.
Many libraries go round the houses to push allocation onto consumer code but that is onerous when the full size of the space required can't be known such as here.
I'd suggest putting _alloc() at the end of any function that returns objects that consumer code must later free().
So the answer for the question posed is remove the malloc() and the free() because the library handles both. However beware if your program makes many calls to that function and others that internally rely on it (like get_double()) you may run out of memory because the library is sitting on dead space.
The problem is your get_strings overrides your initial malloc. A pointer value is a value. By equating it with something else, you replaced your malloc value.
Memory is allocated at the statement:
strings = get_string();
You dont have to malloc it ( char *strings = malloc(sizeof(char) * 10);
)
Without malloc it will work fine
First You have created a dynamic memory which will be pointed by *strings. But then you are pointing to the local string (from get_string() function) using *strings pointer. when you call free, program is trying delete local (stack) reference and throwing error.
To solve that error, the program should be
#include <stdio.h>
#include <cs50.h>
int main (void)
{
char *strings = malloc(sizeof(char) * 10);
printf("What is your name?\n");
//wait for use to type his/her name
strcpy(strings, get_string()); // Use strcpy instead of assigning
printf("Hello %s\n", strings);
free (strings);
return 0;
}
You don't include the code for get_string(), but you're overwriting strings with its return value which is wrong. The address you pass to free() must come from malloc(), and it seems you're violating that (in addition to losing the original returned address for your 10 bytes).
Assuming get_string() returns static storage (i.e. you don't need to free it) you can do this without involving malloc().
If you really want to, something like this might work:
printf("What is your name?\n");
const char *name = get_string();
const size_t nlen = strlen(name);
char * const name_copy = malloc(nlen + 1);
if(name_copy != NULL)
{
memcpy(name_copy, name, nlen + 1);
printf("Hello %s (from my own memory!)\n", name_copy);
free(name_copy);
}
This is rather convoluted but you get the idea.
char *strings;
No need for new malloc as string returned from get_string() function is already on the heap, you just need to pick up pointer to first character. (get_string() function reference)
strings = get_string();
printf("Hello %s\n", strings);
After printing string you should free memory allocated for it, as it is stated in get_string() function reference
Stores string on heap (via malloc); memory must be freed by caller to
avoid leak.
I think everything else is fine, try this code:
#include <stdio.h>
#include <cs50.h>
int main (void)
{
char *strings;
printf("What is your name?\n");
//wait for use to type his/her name
strings = get_string();
printf("Hello %s\n", strings);
free (strings);
return 0;
}
I'm creating a function that returns a string. The size of the string is known at runtime, so I'm planning to use malloc(), but I don't want to give the user the responsibility for calling free() after using my function's return value.
How can this be achieved? How do other functions that return strings (char *) work (such as getcwd(), _getcwd(), GetLastError(), SDL_GetError())?
Your challenge is that something needs to release the resources (i.e. cause the free() to happen).
Normally, the caller frees the allocated memory either by calling free() directly (see how strdup users work for instance), or by calling a function you provide the wraps free. You might, for instance, require callers to call a foo_destroy function. As another poster points out you might choose to wrap that in an opaque struct, though that's not necessary as having your own allocation and destroy functions is useful even without that (e.g. for resource tracking).
However, another way would be to use some form of clean-up function. For instance, when the string is allocated, you could attach it to a list of resources allocated in a pool, then simply free the pool when done. This is how apache2 works with its apr_pool structure. In general, you don't free() anything specifically under that model. See here and (easier to read) here.
What you can't do in C (as there is no reference counting of malloc()d structures) is directly determine when the last 'reference' to an object goes out of scope and free it then. That's because you don't have references, you have pointers.
Lastly, you asked how existing functions return char * variables:
Some (like strdup, get_current_dir_name and getcwd under some circumstances) expect the caller to free.
Some (like strerror_r and getcwd in under other circumstances) expect the caller to pass in a buffer of sufficient size.
Some do both: from the getcwd man page:
As an extension to the POSIX.1-2001 standard, Linux (libc4, libc5, glibc) getcwd() allocates the buffer dynamically
using malloc(3) if buf is NULL. In this case, the allocated buffer has the length size unless size is zero, when
buf is allocated as big as necessary. The caller should free(3) the returned buffer.
Some use an internal static buffer and are thus not reentrant / threadsafe (yuck - do not do this). See strerror and why strerror_r was invented.
Some only return pointers to constants (so reentrancy is fine), and no free is required.
Some (like libxml) require you to use a separate free function (xmlFree() in this case)
Some (like apr_palloc) rely on the pool technique above.
Many libraries force the user to deal with memory allocation. This is a good idea because every application has its own patterns of object lifetime and reuse. It's good for the library to make as few assumptions about its users as possible.
Say a user wants to call your library function like this:
for (a lot of iterations)
{
params = get_totally_different_params();
char *str = your_function(params);
do_something(str);
// now we're done with this str forever
}
If your libary mallocs the string every time, it is wasting a lot of effort calling malloc, and possibly showing poor cache behavior if malloc picks a different block each time.
Depending on the specifics of your library, you might do something like this:
int output_size(/*params*/);
void func(/*params*/, char *destination);
where destination is required to be at least output_size(params) size, or you could do something like the socket recv API:
int func(/*params*/, char *destination, int destination_size);
where the return value is:
< desination_size: this is the number of bytes we actually used
== destination_size: there may be more bytes waiting to output
These patterns both perform well when called repeatedly, because the caller can reuse the same block of memory over and over without any allocations at all.
There is no way to do this in C. You have to either pass a parameter with size information, so that malloc() and free() can be called in the called function, or the calling function has to call free after malloc().
Many object oriented languages (eg. C++) handle memory in such a way as to do what you want to, but not C.
Edit
By size information as an argument, I mean something to let the called function know the how many bytes of memory are owned by the pointer you are passing. This can be done by looking directly at the called string if it has already been assigned a value, such as:
char test1[]="this is a test";
char *test2="this is a test";
when called like this:
readString(test1); // (or test2)
char * readString(char *abc)
{
int len = strlen(abc);
return abc;
}
Both of those arguments will result in len = 14
However if you create a non populated variable, such as:
char *test3;
And allocate the same amount of memory, but do not populate it, for example:
test3 = malloc(strlen("this is a test") +1);
There is no way for the called function to know what memory has been allocated. The variable len will == 0 inside the 1st prototype of readString(). However, if you change the prototype readString() to:
readString(char *abc, int sizeString); Then size information as an argument can be used to create memory:
void readString(char *abc, size_t sizeString)
{
char *in;
in = malloc(sizeString +1);
//do something with it
//then free it
free(in);
}
example call:
int main()
{
int len;
char *test3;
len = strlen("this is a test") +1; //allow for '\0'
readString(test3, len);
// more code
return 0;
}
You cannot do this in C.
Return a pointer and it is up to the person calling the function to call free
Alternatively use C++. shared_ptr etc
You can wrap it in a opaque struct.
Give the user access to pointers to your struct but not its internal. Create a function to release resources.
void release_resources(struct opaque *ptr);
Of course the user needs to call the function.
You could keep track of the allocated strings and free them in an atexit routine (http://www.tutorialspoint.com/c_standard_library/c_function_atexit.htm). In the following, I have used a global variable but it could be a simple array or list if you have one handy.
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
char* freeme = NULL;
void AStringRelease(void)
{
if (freeme != NULL)
free(freeme);
}
char* AStringGet(void)
{
freeme = malloc(20);
strcpy(result, "A String");
atexit(AStringRelease);
return freeme;
}
I have a function like this:
void readString(char* str){
str="asd";
}
Can I know if str will be dealloced? Or must I free it?
Note: I can't use string library as I am programming a microprocessor.
free() must only be called if malloc(), calloc() or realloc() was used to allocate memory. This is not the case in the posted code so calling free() is unrequired.
The "asd" is a string literal and exists for the lifetime of the program (has static storage duration).
Your function does nothing.
It doesn't "read" a string. All it does it assign the address of a string literal (a constant block of memory somewhere that is initialized to the text of the string) to the function's local variable str. The function then exits, causing that local variable to stop existing.
Nothing is returned, and the pointer is not de-referenced (which would in turn be wrong since it's only a char *, not a char * *), so nothing happens outside the function. The caller doesn't "get" any value, and thus has nothing to call free() on, so that problem can never even occur.
String will not be deallocated because it is stored in static memory. You didn't allocate it, you don't free it
No, there is no memory leak. In your case it is statically allocated.
In general you have to make up your own rules about who can or must free memory, and you should document your code so it is clear what the requirements are.
In the example given, readString() only overwrites its own private copy of the pointer, and when it returns the caller will not see that anything has changed. Consequently the caller will have the same duty to free() its pointer as it had before it called readString(), and there will be no leak.
However, if readString() instead accepted a char **, so that it could modify the caller's copy of the pointer, then the outcome would be that it would not be legal to call free() after calling readString(), as the pointer's new value is not part of the malloc heap.
If the previous value of that pointer variable had been a malloc()ed object, then the caller should have freed it before allowing the pointer to be overwritten. It would be truly horrible to have readString() call free() in that case, because it would turn a variable which must eventually be freed into one which must never be freed, and the program flow would be very hard to follow.
This code is useless and meaningless as for as I am concerned. Here are different ways of calling your function definition and why I say this!
int main (int argc, char *argv[], char *envp[])
{
char a, *b, *c;
b = malloc (10);
readString(&a); // Case-1, Valid calling.
readString(b); // Case-2, Valid calling.
readString(c); // Case-3, Invalid calling. Unallocated location.
}
Case-1: This is the only case, where it matters to the caller about what you do in your function. You may use the passed character as you wish. The only meaningful assignment would be something like this. Doing 'str = "asd";' would probably dump the core or mess with the caller's stack or data segment memory(if address of a global variable was passed) and create a complicated debugging nightmare!
void readString(char* str){
*str='a';
}
Case-2: There is nothing Fatal or Syntax error in the code, but it is meaningless to do this. The only meaningful thing would be, just using what ever passed to your function from the caller. What is the reason for assigning like this on the passed parameter? Your definition can just have a local variable and avoid parameter passing completely. That function can be called as "readString();"...
void readString(void){
char *str='asd';
}
I have the following code:
#include <stdio.h>
char * lookLine (FILE *fichero)
{
char p[25];
fgets (p, sizeof (p), fichero);
return p;
}
int main (void) {
printf ("%s\n", lookLine (fopen ("suma.c", "r")));
return 0;
}
And I get the following output:
#��x�
Not nice. My intention is to print out the first line of the file whose name "suma.c". It should print out the following:
#include <stdio.h>
Nevertheless, if I print out the content of p string into the same lookFile function, it does it fine:
#include <stdio.h>
void lookLine (FILE * fichero)
{
char p[25];
fgets (p, sizeof (p), fichero);
printf ("%s\n", p);
}
int main (void) {
lookLine (fopen ("suma.c", "r"));
return 0;
}
And the output I get now is the correct one:
#include <stdio.h>
My reasoning is this: by using fgets I save the string of the first line of "name.c" in the p array and I return its address, which is taken by the second argument of printf function in main.
But I have found out that this only works when I use the printf function directly into the same lookLine function...
Please, could someone tell me what's really going on here?
It's because you are returning a pointer to a local array from the read function.
Remember that local variables are stored on the stack, and that includes arrays. And when the function returns that stack space is reclaimed by the compiler to be used by other function calls. So you have a pointer pointing to another function's memory.
The lifetime of the array p ends at the return statement (technically p is a local variable with automatic storage duration; this means it's lifetime ends at the matching }).
The program then invokes undefined behavior because it uses an indeterminate value (reading from a pointer that no longer points to valid memory). This is the reason you can print the string while still in read(), but get garbage when printing from main().
And note that read is a POSIX function that may be interfering with the one you defined (not a problem in a strict C89 or C99 mode, but most compilers aren't by default). [The OP in the meantime renamed the function to lookLine().]
As pointed to by Joachin Pileborg correctly, you are trying to return a stack variable which will be reclaimed, when you return from the function.
Instead you can try to pass a character array and it's size as inputs to the function read. Btw, if you don't intend to do anything else apart from calling fgets in the read function, then it is better that you call fgets in the main function itself.
Incase if you are doing some additional logic in read and you also cannot pass the buffer and it's size as input to read function, you can allocate the memory required from reading using malloc and return the pointer to the calling function. But, personally, I wouldn't recommend it as it is better to ensure the caller of the read takes the responsibility of creation and deletion of the array.