I'm trying to work with threads in C and i'm having some problems with freeing a pointer
if this is the thread function
void *executor_func(void *param) {
char *lineEx = (char *) malloc (1024);
size_t lenEx = 1024;
ssize_t readEx;
FILE * fpEx;
char* pchEx;
fpEx = fopen(file, "r");
if (fpEx == NULL) {
printf("ERROR: couldnt open file\n");
exit(0);
}
while ((readEx = getline(&lineEx, &lenEx, fpEx)) != -1) {
pchEx = strtok(lineEx, " ");
//DO MY STUFF WITH THE LINE I RECEIVE FROM FILE
}
free(lineEx);
fclose(fpEx);
return NULL;
}
Imagine that i execute multiple threads of executor_func()...
the free(lineEX) is giving me problems at Valgrind... why is that ?
This is from the documentation : http://man7.org/linux/man-pages/man3/strtok.3.html
The strtok() function parses a string into a sequence of tokens. On
the
first call to strtok() the string to be parsed should be specified in str.
In each subsequent call that should parse the same string, str should be
NULL.
As the strtok manual says :
Be cautious when using these functions. If you do use them, note that:
* These functions modify their first argument.
* These functions cannot be used on constant strings.
* The identity of the delimiting byte is lost.
* The strtok() function uses a static buffer while parsing, so it's not
thread safe. Use strtok_r() if this matters to you.
If you get illegal frees maybe it is related to this (from Valgrid manuals):You will also get this message if you try to free a pointer that doesn't point to the start of a heap block.Memcheck keeps track of the blocks allocated by your program with malloc/new, so it can know exactly whether or not the argument to free/delete is legitimate or not. Here, this test program has freed the same block twice. As with the illegal read/write errors, Memcheck attempts to make sense of the address freed. If, as here, the address is one which has previously been freed, you wil be told that -- making duplicate frees of the same block easy to spot.
And lastly have a look at this : strtok function thread safety
You can try to use strtok_r()
Related
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;
}
Does strdup allocate another memory zone and create another pointer every time?
For example: does the following code result in a memory leak?
void x(char** d, char* s){
*d = strdup(s);
}
int main(){
char* test = NULL;
x(&test, "abcd");
x(&test, "etc");
return 0;
}
Yes, the program leaks memory because it allocates objects and then loses references to them.
The first time this happens is in the line:
x(&test, "etc");
The variable test holds the one and only copy of a pointer that was allocated in a previous call to x. The new call to x overwrites that pointer. At that point, the pointer leaks.
This is what it means to leak memory: to lose all references to an existing dynamically allocated piece of storage.*
The second leak occurs when the main function returns. At that point, the test variable is destroyed, and that variable holds the one and only copy of a pointer to a duplicate of the "etc" string.
Sometimes in C programs, we sometimes not care about leaks of this second type: memory that is not freed when the program terminates, but that is not allocated over and over again in a loop (so it doesn't cause a runaway memory growth problem).
If the program is ever integrated into another program (for instance as a shared library) where the original main function becomes a startup function that could be invoked repeatedly in the same program environment, both the leaks will turn into problems.
The POSIX strdup function behaves similarly to this:
char *strdup(const char *orig)
{
size_t bytes = strlen(orig) + 1;
char *copy = malloc(bytes);
if (copy != 0)
memcpy(copy, orig, bytes);
return copy;
}
Yes; it allocates new storage each time.
If you have a garbage collector (such as Boehm) in your C image, then it's possible that the leaked storage is recycled, and so strdup is able to re-use the same memory for the second allocation. (However, a garbage collector is not going to kick in after just one allocation, unless it is operated in a stress-test mode for flushing out bugs.)
Now if you want to actually reuse the memory with realloc, then you can change your x function along these lines:
#include <stdlib.h>
#include <string.h>
void *strealloc(char *origptr, char *strdata)
{
size_t nbytes = strlen(strdata) + 1;
char *newptr = (char *) realloc(origptr, nbytes); /* cast needed for C++ */
if (newptr)
memcpy(newptr, strdata, nbytes);
return newptr;
}
(By the way, external names starting with str are in an ISO C reserved namespace, but strealloc is too nice a name to refuse.)
Note that the interface is different. We do not pass in a pointer-to-pointer, but instead present a realloc-like interface. The caller can check the return value for null to detect an allocation error, without having the pointer inconveniently overwritten with null in that case.
The main function now looks like:
int main(void)
{
char *test = strealloc(NULL, "abcd");
test = strealloc(test, "etc");
free(test);
return 0;
}
Like before, there is no error checking. If the first strealloc were to fail, test is then null. That doesn't since it gets overwritten anyway, and the first argument of strealloc may be null.
Only one free is needed to plug the memory leak.
* It's possible to have a semantic memory leak with objects that the program hasn't lost a reference to. For instance, suppose that a program keeps adding information to a list which is never used for any purpose and just keeps growing.
Yes, it allocates memory and leaks if you don't free it. From the man page:
The strdup() function returns a pointer to a new string which is a duplicate of the string s. Memory for the new string is obtained with malloc(3), and can be freed with free(3).
new_s = strdup(s) is essentially equivalent to:
new_s = malloc(strlen(s)+1);
strcpy(new_s, s);
Consider the following definition for strdup:
#include <string.h>
char *strdup(const char *string);
strdup reserves storage space for a copy of string by calling malloc. The string argument to this function is expected to contain a null character (\0) marking the end of the string. Remember to free the storage reserved with the call to strdup.
You must free the string yourself.
Okay I've read through a massive amount of of the answers here on SO, and many other places but I just can't seem to grasp this simple function. Please forgive me for something so simple I haven't done c/c++ code in over 8 years and I'm very much trying to re-learn, so please have patience...
I've tried many different ways to do this from assigning a string through a function param by shifting in the value to just straight returning it, but nothing seems to work within the while. I also get no errors during compile time, but I do get segfaults at runtime. I would very much like to find out why the following function does not work... I just don't understand why the else returns fine as type char *content, but strcat(content, line); does not. Even though the man pages for strcat shows that strcat's definition should be (char *DEST, const char *SRC). As I currently understand it trying to do a cast to a const char on the line variable within the while would just return an integer to the pointer. So I'm stumped here and would like to be educated by those who have some time!
char * getPage(char *filename) {
FILE *pFile;
char *content;
pFile = fopen(filename, "r");
if (pFile != NULL) {
syslog(LOG_INFO,"Reading from:%s",filename);
char line [256];
while (fgets(line, sizeof line, pFile) != NULL) {
syslog(LOG_INFO,">>>>>>>Fail Here<<<<<<<");
strcat(content, line);
}
fclose(pFile);
} else {
content = "<!DOCTYPE html><html lang=\"en-US\"><head><title>Test</title></head><body><h1>Does Work</h1></body></html>";
syslog(LOG_INFO,"Reading from:%s failed, serving static response",filename);
}
return content;
}
Very much appreciate all the great answers in this post. I would give everyone in the discussion a checkmark but unfortunately I can't...
This is pretty simple, but very surprising if you're used to a higher-level language. C does not manage memory for you, and C doesn't really have strings. That content variable is a pointer, not a string. You have to manually allocate the space you need for the string before calling strcat. The correct way to write this code is something like this:
FILE *fp = fopen(filename, "r");
if (!fp) {
syslog(LOG_INFO, "failed to open %s: %s", filename, strerror(errno));
return xstrdup("<!DOCTYPE html><html lang=\"en-US\"><head><title>Test</title>"
"</head><body><h1>Does Work</h1></body></html>");
} else {
size_t capacity = 4096, offset = 0, n;
char *content = xmalloc(capacity);
size_t n;
while ((n = fread(content + offset, 1, capacity - offset, fp)) > 0) {
offset += n;
if (offset == capacity) {
capacity *= 2;
content = xrealloc(content, capacity);
}
}
if (n < 0)
syslog(LOG_INFO, "read error from %s: %s", filename, strerror(errno));
content[offset] = '\0';
fclose(fp);
return content;
}
Notes:
Error messages triggered by I/O failures should ALWAYS include strerror(errno).
xmalloc, xrealloc, and xstrdup are wrapper functions around their counterparts with no leading x; they crash the program rather than return NULL. This is almost always less grief than trying to recover from out-of-memory by hand in every single place where it can happen.
I return xstrdup("...") rather than "..." in the failed-to-open case so that the caller can always call free(content). Calling free on a string literal will crash your program.
Gosh, that was a lot of work, wasn't it? This is why people tend to prefer to write web apps in a higher-level language. ;-)
You need to allocate memory for content. It has to be big enough for the entire file the way you are doing it. You can either allocate a huge buffer up front and hope for the best, or allocate a smaller one and realloc it as needed.
Even better would be rearranging the code to avoid the need for storing the whole file all at once, although if your caller needs a whole web page as a string, that may be hard.
Note also that you need to return the same type of memory from both your code paths. You can't return a static string sometimes and a heap-allocated string other times. That's guaranteed to call headaches and/or memory leaks. So if you are copying the file contents into a block of memory, you should also copy the static string into the same type of block.
content is just a pointer to a string not an actual string - it has 0 bytes of space reserved for your string. You need to allocate memory large enough to hold hour string. Note that after you will have to free it
char *content=malloc(256);
And your code should be ok - oh and I suggest using strncat
The 2nd assignment to content worked ok before - because you are setting the pointer to point to your const string. If you change content to a malloc'ed region of memory - then you would also want to strncpy your fixed string into content.
Ideally if you can use C++ std::string.
char *foo is only a pointer to some piece of memory holding the characters that form the string. So you cannot use strcat because you don't have any memory to copy to. Inside the if statement you are allocating local memory on the stack with char line[256] that holds the line, but since that memory is local for the function is will disappear once it returns, so you cannot return line;.
So what you really want is to allocate some persistent memory, e.g. with strdup or malloc, so that you can return it from the function. Note that you cannot mix constants and allocated memory (because the user of your function must free the memory - which is only possible if it is not a constant).
So you could use something like this:
char * getPage(const char *filename) {
FILE *pFile;
char *content;
pFile = fopen(filename, "r");
if (pFile != NULL) {
syslog(LOG_INFO,"Reading from:%s",filename);
/* check the size and allocate memory */
fseek(pFile, 0, SEEK_END);
if (!(content = malloc(ftell(pfile) + 1))) { /* out of memory ... */ }
rewind(pFile);
/* set the content to be empty */
*content = 0;
char line [256];
while (fgets(line, sizeof line, pFile) != NULL) {
syslog(LOG_INFO,">>>>>>>Fail Here<<<<<<<");
strcat(content, line);
}
fclose(pFile);
} else {
content = strdup("<!DOCTYPE html><html lang=\"en-US\"><head><title>Test</title></head><body><h1>Does Work</h1></body></html>");
syslog(LOG_INFO,"Reading from:%s failed, serving static response",filename);
}
return content;
}
It is not the most efficient way of doing this (because strcat has to find the end every time), but the least modification of your code.
An earlier answer suggested the solution:
char content[256];
This buffer will not be large enough to hold anything but the smallest files and the pointer content goes out of scope when return content; is executed. (Your earlier line, content = "static.."; is fine, because the string is placed in the .rodata data segment and its pointer will always point to the same data, for the entire lifetime of the program.)
If you allocate the memory for content with malloc(3), you can "grow" the space required with realloc(3), but this introduces the potential for a horrible error -- whatever you handed the pointer to must clean up after the memory allocation when it is done with the data (or else you leak memory), and it cannot simply call free(3) because the content pointer might be to statically allocated memory.
So, you have two easy choices:
use strdup(3) to duplicate the static string each time you need it, and use content = malloc(size); for the non-static path
make your caller responsible for providing the memory; every call needs to provide sufficient memory to handle either the contents of the file or the static string.
I would probably prefer the first approach, if only because the size needed for the second approach cannot be known prior to the call.
content is a wild pointer; the variable contains garbage, so it's pointing somewhere into left field. When you copy data to it using strcat, the data goes to some random, probably bad, location. The cure for this is to make content point somewhere good. Since you want it to outlive your function call, it needs to be allocated someplace besides the function's call stack. You need to use malloc() to allocate some space on the heap. Then the caller will own the memory, and should call free() to delete it when it's no longer needed.
You'll need to change the else part that directly assigns to content, as well, to use strcpy, so that the free() will always be valid. You can't free something that you didn't allocate!
Through all of this code, make sure you remember how much space you allocated with malloc(), and don't write more data than you have space, or you'll get more crashes.
I've written a function to test if a given path is a valid Maildir directory (standard Maildir has the three subfolders "cur" "new" and "tmp" ). Function takes in the supposed directory, checks for those subfolders, and returns appropriately.
I'm getting a segfault at the second free statement with the current code, and I similarly got an "invalid next size" error with code of slightly different organization. Even more confusing, it only segfaults on some directories, while successfully completing on others, with no discernible reason (though it is consistent on which ones it will segfault on). With the second free() commented out, all accurately-formatted directories complete successfully.
Obviously I'm double-freeing. My question is, why and how? If the first free is inside the conditional statement and we return immediately after freeing, we never get to the second free. If we get to the second free, that means we skipped the first one... right?
I realize in this context it's perfectly fine because the system will reclaim the memory at the end of the program, but I'm more interested in the reason this is happening than in just making the code work. What if I were looking at a different situation, functions called by functions called by functions etc. and memory could possibly be a concern? Don't I need that 2nd free to reclaim memory?
int is_valid_folder(char* maildir)
{
struct stat *buf;
buf = (struct stat *) malloc(sizeof(struct stat));
char* new = strdup(maildir);
char* cur = strdup(maildir);
char* tmp = strdup(maildir);
strcat (cur, "/cur"); strcat (new, "/new"); strcat (tmp, "/tmp");
if(stat(cur, buf) || stat(tmp, buf) || stat(new, buf))
{
printf("Problem stat-ing one of the cur/new/tmp folders\n");
printf("Error number %d\n", errno);
free(buf);
return 1;
}
free(buf);
return 0; //a valid folder path for this function
}
You have several buffer overflows: strdup() probably allocates a char array that is just large enough to hold the maildir string, and the calls to strcat() will then overflow the arrays. (strcat(), as opposed to strdup(), does not create a new char array, so you must ensure yourself that the array you give it is large enough to hold the resulting string.)
By the way, valgrind is your friend when it comes to tracking down memory management bugs.
There's not enough space in the duplicate strings for the concatenation.
try:
char* new = (char*)calloc(strlen(maildir) + 5);
etc
I know you got it, but just as a tip... (too big for a comment)
Check the return value of strdup() for NULL and free() those pointers when you are done with them. If you don't memory will leak (it is leaking in your current code).
The strdup() function shall return a pointer to a new string, which is a duplicate of the string pointed to by s1. The returned pointer can be passed to free(). A null pointer is returned if the new string cannot be created.
I am somewhat confused by what happens when you call strtok on a char pointer in C. I know that it modifies the contents of the string, so if I call strtok on a variable named 'line', its content will change. Assume I follow the bellow approach:
void function myFunc(char* line) {
// get a pointer to the original memory block
char* garbageLine = line;
// Do some work
// Call strtok on 'line' multiple times until it returns NULL
// Do more work
free(garbageLine);
}
Further assume that 'line' is malloced before it is passed to myFunc. Am I supposed to free the original string after using strtok or does it do the job for us? Also, what happens if 'line' is not malloced and I attempt to use the function above? Is it safer to do the following instead? (Assume the programmer won't call free if he knows the line is not malloced)
Invocation
char* garbageLine = line;
myFunc(line);
free(garbageLine);
Function definition
void function myFunc(char* line) {
// Do some work
// Call strtok on 'line' multiple times until it returns NULL
// Do more work
}
strtok() will not free anything, as it has no knowledge of where the string is stored. It could be on the stack or the heap, it doesn't know or care! :)
Is it safer to do the following instead?
Your second example is much better, as it simplifies myFunc(), and makes it useful in more situations as the function does not need to know where the string is allocated. By removing the call to free() from myFunc() you are able to use the function to parse strings from the stack or the heap. The caller allocates the memory, the caller frees the memory!
Further reading:
strtok()
It's worth explaining that strtok does its job by:
returning pointers that point INTO the original string; and
replacing each separator character that it finds with NULL.
Thus, everything is in-place, and it does not need to allocate any memory.
In the comment in your question, you say that you "Call strtok on 'line' multiple times until it returns NULL". This sounds as if you may be using strtok incorrectly. The first time you call it, you should call it with 'line' as an argument; on subsequent calls, you should pass it NULL. Take the following as an example:
void function myFunc(char* line) {
char *segment; // This will point at each delimited substring in turn.
segment = strtok(line, " ");
// Do something with segment.
segment = strtok(NULL, " ");
// Do something with the new segment.
free(line);
}
As DrTwox said, though, your second example is better - 'line' should be freed by the same context that malloced it (or not), so the call to free() doesn't belong in this function. And you're better off looping it - something like:
void function myFunc(char* line) {
char *segment;
segment = strtok(line, " ");
while (segment != NULL) {
// Do something with segment.
segment = strtok(NULL, " ");
}
}
Invocation is like this:
char *line = malloc(20*sizeof(char));
// Check that malloc succeeded here.
// Put some data into 'line'.
myFunc(line);
free(line);
// No 'garbageLine' required.
The way that strtok works is a little complex to explain, but you've got the important parts - it doesn't allocate or free any memory. Instead, it works by modifying the string you passed to it.
What does this have to do with strtok()? If you allocate memory, you need to free it. Where your application decides to allocate and free the memory is up to you. But if you pass the memory to strtok(), that makes no difference as far as if or when the memory is allocated or freed.
strtok no more frees memory than strlen does. Why would you expect it to? What memory would it free? Perhaps you think strtok needs to free memory because it stores a NUL, but the content of memory is irrelevant. When you allocate memory, the allocator tracks the size of the block you allocated, and the entire block is freed when you free it.