I am getting the memory leak due to first malloc call. I tried to comment out and free but there is no way that I can fix it.
The code wants to parse the query than put the information inside the map. At the same time it is going to update struct too
row_ = atoi(strtok(NULL,",:"));
col_ = atoi(strtok(NULL,",:"));
}
}
For starters this for loop
for(int j = 0; j < strlen(query); j++){
if(!strcmp(&query[j], ",")){
count++;
}
}
does not make a sense. It seems you mean instead
for(int j = 0; j < strlen(query); j++){
if( query[j] == ',')){
count++;
}
}
You allocated memory and its address is assigned to the pointer type.
char* type = malloc(sizeof(char *));
// char* char_name= (char *)malloc(1);
then the pointer was reassigned
type = strtok(query, ",:");
So the address of the allocated memory is lost and you have a memory leak.
This commented declaration
char* char_name= (char *)malloc(1);
also invokes a memory leak due to the statement
char_name = strtok(NULL,",:");
This statement
char_name = realloc(char_name, sizeof(char_name)+1);
does not make a sense at least because sizeof( char_name ) is equivalent to sizeof( char * ). It seems you mean at least
char_name = realloc(char_name, strlen(char_name) + 2 );
But in any case you may not reallocate the memory using the pointer because it does not point to a dynamically allocated memory after this statement
char_name = strtok(NULL,",:");
examine these 2 lines of code
char* type=malloc(sizeof(char *)); <<<<<<=======
// char* char_name= (char *)malloc(1);
int row_,col_;
int count =0;
for(int j=0;j<strlen(query);j++){
if(!strcmp(&query[j],",")){
count++;
}
}
count=(count+1)/3;
type = strtok(query, ",:"); <<<<<<=======
You malloc some memory, do nothing with it and then overwrite the pointer. So now there is no way to free it or use it.
As far as I can see you just need
char*type = NULL;
and take out the frees of type too.
Note - I have not verified the rest of the code. Just answered your leak question. The way you are using strtok is certainly not idiomatic. And I suspect that you think
type = strtok(query, ",:");
copies the first token into the buffer pointed at by type. It does not, what you need is this
type = strdup(strtok(query, ",:"));
Likewise the assignments in the loop
char_name = strtok(NULL,",:");
char_name = realloc(char_name, sizeof(char_name)+1);
are very wrong. You cannot realloc the return of strtok. Again you need
char_name = strdup(strtok(NULL,",:"));
Related
char **loadValues()
{
char **toReturn;
int i;
toReturn = malloc(5 * sizeof(char *));
for (i = 0; i < 5; i++)
{
toReturn[i] = malloc(25); //Change the size as per your need
strncpy(toReturn[i], "string", i + 1); //Something to copy
}
return toReturn;
}
I copied above part of the code. In it, the "toReturn" variable is initialized by using malloc. Don't we have to "free" this "toReturn" variable?
Don't we have to free these variables when we return them in C. I still couldn't find a clear answer and I can't find a way to free it when I return it. Can someone explain it to me?
I assume that your question is: how does the function that calls loadValues and receives the pointer it returns, can free the loaded values.
If we leave loadValues as it is now, the best solution is to create another function, called freeValues and call it when we are done with the values:
void freeValues(char **values)
{
for (i = 0; i < 5; i++)
{
free(values[i]);
}
free(values);
}
Then you can do something like this in your main program:
char **values = loadValues();
// ... use values for something
freeValues(values);
Another option, is to allocate toReturn using a single call to malloc, in which case it can be freed simply by calling to free.
You cannot free the allocated memory inside the function and return that data so that it can be used outside the function. But you still can free() the memory outside the function.
Don't we have to "free" this "toReturn" variable?
Yes, eventually you'd want to free the memory after you're done with it.
I still couldn't find clear answer and I can't find a way to free it when I return it. Can someone explain it to me?
When you use the function you assign it to a new pointer, you can use this pointer, not only to access the memory block you returned, but also to free it, example:
int main()
{
char** values = loadValues();
// do something with values
// don't need them anymore
for (int i = 0; i < 5; i++){
free(values[i]);
}
free(values);
}
Note that strncpy(toReturn[i], "string", i + 1); is likely not what you want, in each iteration you are copying only from 1 to 5 characters respectively, not the entire string, and more importantly, not the null terminator.
The third argument of strncpy should be the length of "string" plus 1 more byte for the null terminator, so 7 in this case. Alternatively, if want to copy only part of ther string, you have to null-terminate it yourself.
If the goal is to copy the entire string, you can let the compiler do that for you:
//...
toReturn = malloc(5 * sizeof(char *));
for (i = 0; i < 5; i++)
{
toReturn[i] = strdup("string"); // duplicate string and store it in toReturn[i]
}
//...
Of course you still need to free it yourself like in the first situation.
I have a function
populateAvailableExtensions(const char** gAvailableExtensions[], int gCounter)
which take a pointer to an array of strings and the number of elements in the array as parameters.
I allocate initial memory to that array using malloc(0). Specs say that it will either return a null pointer or a unique pointer that can be passed to free().
int currentAvailableExtensionCount = gCounter;
This variable will store number of string in gAvailableExtensions.
Inside this for loop
for (int i = 0; i < availableExtensionCount; ++i)
I have this piece of code
size_t sizeOfAvailableExtensionName =
sizeof(availableExtensionProperties[i].name);
reallocStatus = realloc(*gAvailableExtensions, sizeOfAvailableExtensionName);
memcpy(&(*gAvailableExtensions)[currentAvailableExtensionCount],
&availableExtensionProperties[i].name,
sizeOfAvailableExtensionName);
++currentAvailableExtensionCount;
where
availableExtensionProperties[i].name
returns a string.
This is how that struct is defined
typedef struct Stuff {
char name[MAX_POSSIBLE_NAME];
...
...
} Stuff;
realloc(*gAvailableExtensions, sizeOfAvailableExtensionName);
should add memory of size sizeOfAvailableExtensionName to *gAvailableExtensions de-referenced array.
memcpy(&(*gAvailableExtensions)[currentAvailableExtensionCount],
&availableExtensionProperties[i].name,
sizeOfAvailableExtensionName);
should copy the string (this sizeOfAvailableExtensionName much memory) from
&availableExtensionPropterties[i].name
address to
&(*gAvailableExtensions)[currentAvailableExtensionCount]
address.
But I don't think the code does what I think it should because I'm getting this error
realloc(): invalid next size
Aborted
(core dumped) ./Executable
EDIT: Full code
uint32_t populateAvailableExtensions(const char** gAvailableExtensions[], int gCounter) {
int currentAvailableExtensionCount = gCounter;
void* reallocStatus;
uint32_t availableExtensionCount = 0;
vkEnumerateInstanceExtensionProperties(
VK_NULL_HANDLE, &availableExtensionCount, VK_NULL_HANDLE);
VkExtensionProperties availableExtensionProperties[availableExtensionCount];
vkEnumerateInstanceExtensionProperties(
VK_NULL_HANDLE, &availableExtensionCount, availableExtensionProperties);
for (int i = 0; i < availableExtensionCount; ++i) {
size_t sizeOfAvailableExtensionName =
sizeof(availableExtensionProperties[i].extensionName);
reallocStatus = realloc(*gAvailableExtensions, sizeOfAvailableExtensionName);
memcpy(&(*gAvailableExtensions)[currentAvailableExtensionCount],
availableExtensionProperties[i].extensionName,
sizeOfAvailableExtensionName);
++currentAvailableExtensionCount;
}
return currentAvailableExtensionCount;
}
This is how an external function calls on that one,
uint32_t availableExtensionCount = 0;
availableExtensions = malloc(0);
availableExtensionCount = populateAvailableExtensions(&availableExtensions);
and
const char** availableExtensions;
is declared in header file.
EDIT 2: Updated the code, now gCounter holds the number of elements in gAvailableExtensions
This loop is totally messy:
for (int i = 0; i < availableExtensionCount; ++i) {
size_t sizeOfAvailableExtensionName =
sizeof(availableExtensionProperties[i].extensionName);
reallocStatus = realloc(*gAvailableExtensions, sizeOfAvailableExtensionName);
memcpy(&(*gAvailableExtensions)[currentAvailableExtensionCount],
availableExtensionProperties[i].extensionName,
sizeOfAvailableExtensionName);
++currentAvailableExtensionCount;
}
I assume the only lines that does what you expect them to do, are the lines for (int i = 0; i < availableExtensionCount; ++i) and ++currentAvailableExtensionCount;
First, the typical way to use realloc is like this:
foo *new_p = realloc(p, new_size);
if (!new_p)
handle_error();
else
p = new_p;
The point is that realloc will not update the value of p if a reallocation happens. It is your duty to update 'p'. In your case you never update *gAvailableExtensions. I also suspect that you don't calculate sizeOfAvailableExtensionCount correctly. The operator sizeof always return a compile time constant, so the realloc doesn't actuall make any sense.
The memcpy doesn't actally make any sense either, since you are copying the string into the memory of a pointer array (probably with an additional buffer overflow).
You said that *gAvailableExtensions is a pointer to an array of pointers to strings.
That means that you have to realloc the buffer to hold the correct number of pointers, and malloc memory for each string you want to store.
For this example, I assume that .extensionName is of type char * or char[XXX]:
// Calculate new size of pointer array
// TODO: Check for overflow
size_t new_array_size =
(currentAvailableExtensionCount + availableExtensionCount) * sizeof(*gAvailableExtensions);
char **tmp_ptr = realloc(*gAvailableExtensions, new_array_size);
if (!tmp_ptr)
{
//TODO: Handle error;
return currentAvailableExtensionCount;
}
*gAvailableExtensions = tmp_ptr;
// Add strings to array
for (int i = 0; i < availableExtensionCount; ++i)
{
size_t length = strlen(availableExtensionProperties[i].extensionName);
// Allocate space for new string
char *new_s = malloc(length + 1);
if (!new_s)
{
//TODO: Handle error;
return currentAvailableExtensionCount;
}
// Copy string
memcpy (new_s, availableExtensionProperties[i].extensionName, length + 1);
// Insert string in array
(*gAvailableExtensions)[currentAvailableExtensionCount] = new_s;
++currentAvailableExtensionCount;
}
If you can guarantee that the lifetime of availableExtensionProperties[i].extensionName is longer than *gAvailableExtensions, you can simplify this a little bit by dropping malloc and memcpy in the loop, and do:
char *new_s = availableExtensionProperties[i].extensionName;
(*gAvailableExtensions)[currentAvailableExtensionCount] = new_s;
Some harsh words at the end: It seems like you have the "Infinite number of Monkeys" approach to programming, just hitting the keyboard until it works.
Such programs will just only give the illusion of working. They will break in spectacular ways sooner or later.
Programming is not a guessing game. You have to understand every piece of code you write before you move to the next one.
int currentAvailableExtensionCount =
sizeof(*gAvailableExtensions) / sizeof(**gAvailableExtensions) - 1;
is just a obfuscated way of saying
int currentAvailableExtensionCount = 0;
I stopped reading after that, because i assume that is not what you intend to write.
Pointers in c doesn't know how many elements there are in the sequence they are pointing at. They only know the size of a single element.
In your case *gAvailableExtensions is of type of char ** and **gAvailableExtensions is of type char *. Both are pointers and have the same size on a typical desktop system. So on a 64 bit desktop system the expression turns into
8/8 - 1, which equals zero.
Unless you fix this bug, or clarify that you actually want the value to always be zero, the rest of the code does not make any sense.
I am debugging some code written by someone else which has several memory leaks detected by Valgrind. Part of the code which I believe is causing the problems involves void pointers:
int noElements = 100;
void** ptr = malloc( noElements * sizeof(void*));
for(int i = 0; i < noElements; i++)
{
ptr[i] = malloc(sizeof(void*));
}
//Operation filling the array and doing calculation
free(ptr); //This will not clear the underlying array causing the memory leak?
I created a small test program to check the error is where I thought it was (not freeing each ptr[i] before calling free(ptr);), but I am getting errors when trying to free elements. My test program looks like this:
int main()
{
int num = 10000000; //Large array so I can clearly see memory usage
void** ptr = (void**) malloc(sizeof(void*) * num);
for (int i = 0; i < num; i++)
{
ptr[i] = malloc(sizeof(void*));
ptr[i] = &i; //If I never point elements at anything, this code works
}
for (int i = 0; i < num; i++)
{
free(ptr[i]); //Crashes here if the elements have been pointed at a variable
}
free(ptr);
return 0;
}
Why would calling free on each array element cause the program to crash if the pointers have actually been assigned?
In your code
ptr[i] = &i;
creates three issues.
It makes the actual returned pointer by malloc() to be lost (you're overwriting it), so you have no shot at free()-ing it later, leading to memory leak.
i is a local scoped variable (the scope of for loop body), and you're storing the address of the variable to be used outside the scope (i.e., after the lifetime is over). Outside the scope attempt to access the address of it will invoke undefined behavior.
(Ignoring point 2) Attempt to free() the ptr[i] will cause undefined behavior again, as the pointer is not returned by memory allocator function.
Your pointers have been assigned a value which is not what you want.
for (int i = 0; i < num; i++)
{
ptr[i] = malloc(sizeof(void*));
ptr[i] = &i; //If I never point elements at anything, this code works
}
First you assign a valid memory address that is returned by malloc().
This address could be free'd using free().
But then you assign another address. The address of your local variable i. This memory location was not allocated using malloc() and hence cannot be free'd. By assigning this address you've lost the dynamically allocated address causing a memory leak.
Your comment is wrong. You already assigned a value that ptr[i] points to some valid address. You don't need to assign again. And you should not.
char** removeDuplicateChromosomes(char* input[], int no_of_chromosomes)
{
char** result = (char**) malloc(sizeof(char* )*(no_of_chromosomes));
//some piece of code
result[count] = input[itr];
//some piece of code . I didn't free any pointers here in this function
return result;
}
Can someone help me to identify any dangling pointers (if present) and explain the same pls?
Memory leak - if no pointer points to unfreed memory.
Dangling pointer - a pointer that points to freed memory.
Your code has a significant risk of either / both, though without a complete code sample, it's impossible to tell whether either would occur. I'll just give some possible scenario's of when it could happen.
As an initial note, If you don't free result's memory in the calling function, you'd have a memory leak. Any malloc must have a corresponding free.
If you free input like this:
free(input);
There would not be a dangling pointer.
But then there may be a memory leak if each element of input doesn't have an element of result pointing to the same memory. And if multiple elements of result point to this memory, you'll probably end up with a dangling pointer when you try to free it, along with some undefined behaviour.
If you free input like this:
int i;
for (i = 0; i < inputSize; i++)
free(input[i]);
free(input);
There would be a dangling pointer.
Why?
input[itr]; is a pointer.
result[count] = input[itr]; just makes result[count] point to the same memory as what input[itr] points to.
So if we free input[itr], result[count] would point to freed memory, and thus be dangling.
If we don't free input[itr], result[count] will still point to valid memory.
If you want result[count] to point to its own memory, you'll have to use:
result[count] = malloc(inputItrSize);
memcpy(result[count], input[itr], inputItrSize);
Note - there's no way to tell how much memory input[itr] is pointing to, so you'll have to declare inputItrSize with the appropriate size yourself.
A dangling pointer is a pointer to a memory area that is no-longer allocated.
char* dangleMeBaby(char* obj) {
free(obj);
return obj;
}
int* localDangle() {
int i = 10;
return &i;
}
#define NUM_POINTERS 8
char** wholeLottaDangle() {
char* ptr = malloc(sizeof(char*) * NUM_POINTERS);
size_t i;
void* data = malloc(NUM_POINTERS);
for (i = 0; i < NUM_POINTERS; ++i) {
ptr[i] = data + i;
}
free(data); // all the pointers in ptr now dangle.
free(ptr); // and ptr itself is now a dangle
return ptr;
}
If you have allocated input as one big block of pointers + data, then freeing input before result will turn result into an array of dangling pointers.
size_t indexSize = sizeof(char*) * numChromosomes;
size_t chromosomeSize = (MAX_CHROMOSOME_LEN) * numChromosomes;
char* data = malloc(indexSize + chromosomeSize);
char** input = (char**)data;
char* chromosome = data + indexSize;
for (size_t i = 0; i < numChromosomes; ++i, chromosome += MAX_CHROMOSOME_LEN) {
input[i] = chromosome;
}
// no dangling pointers in result until you free input.
If you have allocated chromosomes individually and then allocated "input" to house all the pointers, then freeing a chromosome without removing it from "result" will cause a dangling pointer
result = removeDuplicateChromosomes(input, 64);
free(input[0]); // result still points to it, result is dangling.
But if input and the list of chromoes remain intact until you free input() and/or any chromosomes, you have no dangling pointers.
Yesterday I asked a similar question regarding how to free allocated memory for a sub-string. Now I have one more question regarding the same problem (involving a set of conditions), how could I free the following sub-string without doing double free?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct st_ex {
char product[16];
float price;
};
struct st_temp {
char *prod;
};
char *temp = NULL;
// from stackoverflow
char* substr( const char* source, size_t start, size_t end )
{
char* dest = malloc( end - start + 1) ;
memcpy( dest, &source[start], end - start ) ;
dest[end - start] = 0 ;
return dest ;
}
int main()
{
struct st_ex structs[] = {{"mp3 player", 2.0f}, {"plasma tv", 20.0f},
{"notebook", 10.0f}, {"smartphone", 49.9f},
{"dvd player", 10.0f}, {"matches", 0.2f }};
struct st_temp **temp_struct;
size_t j, i;
temp_struct = malloc(sizeof *temp_struct * 6);
for (j = 0; j < 6; j++)
temp_struct[j] = malloc(sizeof *temp_struct[j]);
size_t structs_len = sizeof(structs) / sizeof(struct st_ex);
// NOTE: that structs_len may vary in size - not just 6
for(i=0; i<structs_len; i++){
if (i == 0)
temp_struct[i]->prod = "+";
else if(i == 1)
temp_struct[i]->prod = "Bar";
else if(i == 5)
temp_struct[i]->prod = "Foo";
else {
temp = substr(structs[i].product, 0, 4);
temp_struct[i]->prod = temp;
}
}
for(i=0; i<6; i++ )
printf("%s\n",temp_struct[i]->prod);
for(i = 0; i < 6; i++ ){
/* can I do something like this? */
/*if (i != 0 || i != 1 || i != 5)*/
free(temp_struct[i]->prod);
free(temp_struct[i]);
}
free(temp_struct);
return 0;
}
The problem is that sometimes you set temp_struct[i]->prod to a quoted string ("Bar") which you cannot free and sometimes to the result of a substr call, which you must free.
The easiest solution is to always set it to a string that you must free.
temp_struct[i]->prod = new_string("Bar");
where
char* new_string( const char* source )
{
char* dest = malloc( strlen(source) + 1 ) ;
strcpy(dest, source);
return dest ;
}
or, you have to keep track if you need to free or not
struct st_temp {
char *prod;
int prod_must_be_freed;
};
set prod_must_be_freed to 0 or 1 and check that before you free.
And, finally, the whole thing would be improved by using functions to manipulate these structs rather than just fiddling with them directly. Then you could make a free_st_temp(st_temp*) that checked if prod should be freed, and then freed the struct. Your loop would be
for(i = 0; i < 6; i++ ){
free_st_temp(temp_struct[i]);
}
Substrings do not take up extra memory. They are pointers to parts of already existing strings.
Yes, given that your substr is allocating the memory for the substring with malloc, it's reasonable (necessary, really) to free that memory when you're done with it. That said, I think the way you're doing things right now is extremely fragile and error-prone (to put it mildly). If you have any choice at all, I'd allocate the strings for all the prod members the same way -- if you can't allocate them all statically, then allocate them all dynamically, so when you're freeing structures, you can do so uniformly. Trying to assure that you keep the subscripts matched up to free prod if and only if it was allocated dynamically is practically begging for trouble.
You have an additional problem. When you do temp_struct[i]->prod = "Bar"; You are assigning a const char* to prod. That pointer cannot be freed (the most likely outcome is a crash). So if you want to have your code set up this way such that prod can point to either dynamic memory that you got from malloc or to a constant string literal, you need to also keep track of which one it is and only free the dynamic memory.
The condition in your comment would technically work, but would be very poor form. The best idea is to not mix and match string types in the same pointer. But if you insist on doing it that way, then an improvement would be to add another variable to your struct that is set true when prod needs to be freed and false when it does not.
Yes, although you will want to uncomment that if, and change the conditions in the if to be joined with && rather than || (otherwise it will always be true -- every number is either not equal to zero or not equal to one!)
The substrings stored in temp_struct[i]->prod for i other than 0, 1, and 5, were allocated inside the substr function with malloc, so you can and should deallocate them with free.
Similarly, each temp_struct element was allocated with malloc, and so can and should be deallocated with free.
I'm not sure where you think the double free would be coming from. Are you thinking that when you call free(tmp_struct[i]) the memory pointed to by tmp_struct[i]->prod will also be freed? That isn't the case. When you free a pointer to a structure that contains pointers, the memory for the structure's pointers themselves is deallocated (being that it is part of the structure), but the memory being pointed to by those pointers is not, and must be deallocated seperately (since it is external to the structure). Aside from the mistake in the if condition, the way you have it written is the correct way to do this.