How would i free the memory that is leaking fromt he following code.
struct object_one{
int value;
}*object,object_node;
struct node_one {
void **pointers;
}*node, node_node;
node sample(){
object number;
node node123;
node123 = malloc(sizeof(node_node));
number = malloc(sizeof(object_node));
number->valu = malloc(sizeof(int));
number->value = 9;
node123->pointers[0]=number;
free(number);
return node123;
}
Am I doing the correct way to deallocate the memory referenced by number.Once i do the above one, i get the error;
Invalid read of size 4
==15957== at 0x403804: main (abc.c:1255)
==15957== Address 0x540cb50 is 0 bytes inside a block of size 4 free'd
Please suggest me how can I prevent the memory leak in this condition? Thanks in advance.
[EDIT]
Hi actually the above mentioned is not the real code I have. But I have tried my best to refelect the sturcutre and semantics of my code. Actually I am implementing a data strcture. number is some temproary storage and node123 is my real data-base. I would like to assign the value of number in the database and dereference it.number type is a component of database.
[EDIT2]
The code corresponding to line 1255 is printing for the value that is holded by the object i'e value.It looks like:
object tempObject;
tempObject = search_object(root,50);
[1255] printf("Key is %d ------>value is %d\n",50,tempObject->value);
Here the functionsearch_object searches the value corresponding to the key 50. The function is returning the proper value associated with the key and still it is showing such error.
You also need to free(node123).
But this is not what the error message is telling you.
You are also dereferencing a pointer that doesn't point at valid memory (on the line node123->pointers[0] = number). You have not allocated any memory for pointers to point at, so dereferencing it like this will write to a random area in memory.
You forgot to free(node123), it seems.
For each malloc() call you must have a free() call.
The valgrind error you show is not a memory leak, it's an invalid read in a memory region that has been free'd.
It happens in abc.c at line 1255.
You forgot a free(node123);
And also this line: node123->pointers[0]=number; is a trouble.
You didn't initialized pointers inside node123.
Related
I'm trying to make a program that basically picks a specific piece of source code and adds some other specific code into it. The program is just to big to put it all inside my question, but basically I have this "actors" struct:
typedef struct actors_s {
int num;
char *src_path;
char *project_path;
int *papify;
char *actor_path[];
} actors_s;
As you can see these are almost all pointers and the last one is an array of strings. This needs to be done this way because the number of "actor elements" depends on the input every time.
The problem:In an specific test case, I have a case with 'num' members in the actor_path array. Then I first call malloc only once this way:
*actors->actor_path = malloc(actors->num);
My logic tells me I shouldn't be using the '*' operator here but without it I get an error, this is possibly where the problem is. So, a function is called that allocates a new memory space for every new member (never going further of 'num' members):
int size = strlen(name)+strlen(actors->project_path)+strlen("/src/")+strlen(".c")+4;
actors->actor_path[i] = malloc(size);
(The malloc calls are properly tested if successful in the actual program)
This is called inside a function that is called for every "actor_path" element. In this test example I have three actors.
Mysteriously enough, on the third call of this malloc, the src_path element of the struct, which was properly allocated and set to a string once in the beginning of the program (and never touched again) is freed (I think so, at least it is changed into random numbers and symbols if I watch it in debug mode).
Anyone has any idea how and why is this possible? How do I fix this?
Thanks in advance.
EDIT:
Here are some screenshots from the debug watch window: http://imgur.com/a/aB1uv
First call to malloc: all OK.
Second call to malloc: all OK.
Third call to malloc: src_path gets erased!!
[] in latest array element is called flexible array member. It means structure have an array that starts just after structure itself, and its size is unspecified. You have to allocate memory for this manually. E.g.
actors_s *actor = malloc(sizeof(*actor) + sizeof(char*) * num);
Then just assign at most num elements into actor_path (each element is pointer to char).
about *actors->actor_path = malloc(actors->num);
actors->actor_path is an array of pointers, so *actors->actor_path is the first pointer in actors->actor_path, i.e. actors->actor_path[0].
When doing this, you actually allocate actors->num bytes memory for actors->actor_path[0].
Now, accessing actors->actor_path[0] is OK, while accessing actors->actor_path[1], actors->actor_path[2], actors->actor_path[3],... may cause problems, say, rewrite src_path...
about the solution
#keltar is right. In this way, the resource for actors->actor_path[0], actors->actor_path[1], actors->actor_path[2], ..., actors->actor_path[num - 1] is correctly allocated.
The following is from the Libaiff library. I get the following error completely randomly (i.e. sometimes my program works flawlessly and sometimes it gets stuck with this error and it always breaks at the same point within this function).
(1949,0x7fff7b82d310) malloc: * error for object 0xd00000000b400: pointer being freed was not allocated
* set a breakpoint in malloc_error_break to debug
My question is, if r->buffer2 has already been freed, then is it possible for the control to get past the statement if (r->buffer2) and into the block to try and execute free(r->buffer2)? In other words, if r->buffer2 has been freed, shouldn't the if (r->buffer2) prevent the freeing from trying to happen again?
static void AIFF_ReadClose(AIFF_Ref r)
{
if (r->buffer)
free(r->buffer);
if (r->buffer2)
free(r->buffer2); // THIS IS WHERE THE BREAK OCCURS EVERYTIME
Unprepare(r);
fclose(r->fd);
free(r);
return;
}
EDIT:
The following is the definition for AIFF_Ref:
struct s_AIFF_Ref {
FILE* fd;
int flags;
int stat; /* status */
int segmentSize;
int bitsPerSample;
int nMarkers;
int nChannels;
double samplingRate;
uint64_t nSamples;
int markerPos;
uint64_t len;
uint64_t soundLen;
uint64_t pos;
uint64_t sampleBytes;
uint64_t commonOffSet;
uint64_t soundOffSet;
uint64_t markerOffSet;
IFFType format;
IFFType audioFormat;
void* decoder;
void* pdata;
void* buffer;
size_t buflen;
void* buffer2;
size_t buflen2;
int tics;
};
typedef struct s_AIFF_Ref* AIFF_Ref;
Can anyone suggest why this strange behavior might be happening and how I might solve it?
Thanks.
From the documentation,
The free function deallocates a memory block (memblock) that was
previously allocated by a call to calloc, malloc, or realloc.( Assume first free case )
If memblock is NULL, the pointer is ignored and free immediately returns. (You never came here because, you never set your pointer to NULL)
Attempting to free an invalid pointer (a pointer to a memory block
that was not allocated by calloc, malloc, or realloc) may affect
subsequent allocation requests and cause errors. ( Assume second free case )
if (r->buffer2)
{
free(r->buffer2);
r->buffer2 = NULL ; // Always set the pointer to NULL,
// if you doubt that you may gonna 'free' the memory again,
// somewhere else.
}
if (r->buffer2)
{
free(r->buffer2);
r->buffer2 = NULL ;
}
This is because, when you free the memory, the free assures you that the memory will be free'd but it doesn't assures you that it will delete or NULL'ify the value written in the pointer variable. So, if( r->buffer2 ) holds TRUE for your case and hence, the flow enters the if block.
When you received the error message, one possibility was that it had been freed before, another possibility was that the value of the pointer had been changed to point to another memory.
To avoid this, you must pay attention not to change the pointer before you free it and after having freed memory, you should set the point to NULL.
According to the documentation you liked to, you're already provided with open and close functions, namely
AIFF_Ref AIFF_OpenFile(const char* name, int flags) ;
and
int AIFF_CloseFile(AIFF_Ref r) ;
This call should deallocate memory. Have you tried that?
The short answer to your question is no. Calling free(r->buffer2) does not prevent if (r->buffer2) from evaluating to true and subsequently calling free again. The reason is that free(r->buffer2) does not modify the value of r->buffer2. Think of it this way: if you hired a demolition company to go destroy a building, and you handed them a card with the address of the building you wanted destroyed, would the address written on the card suddenly disappear after they destroyed the building? No. A pointer is no different. It's just an address, stored in a variable that we call a "pointer" because it identifies a memory address. The piece of memory it points to is not the same thing as the pointer itself.
As to what is causing the duplicate call to free(), you haven't provided enough information to ascertain that, so one can only speculate.
Please find your question to response and some additional information which might be useful.
if r->buffer2 has been freed, shouldn't the if (r->buffer2) prevent
the freeing from trying to happen again?
There is no way to know the information that whether memory has already been freed or not. As someone has pointed out that checking pointer with 'null' does some sanity check and normally we do in that way. But this would work only when is your logic somebody set the pointer with 'null' after freeing the memory, otherwise the 'null' check would not work and your current code would execute the 'free' as the pointer is not assigned to 'null' while freeing the memory.
By looking the address, it looked to me that the 'buffer2' has some garbage value and you should be getting different address value whenever you might be running your program. This might occur in the scenario where 'AIFF_Ref' object might not have been initialized properly and still it holds some garbage value. One way to do it is to set
memset((void*)r, 0, sizeof(struct s_AIFF_Ref));
This would intialize all with default values. This may avoid the chances of any garbage value assigned to yout 'buffer2' variables.
You have mentioned that these are logic of some library hence I would recommend you to use some dynamic tool to understand the error quickly and and at the point where problem is happening.From your description it is also possible that your program has some sort of memory corruption. I think my previous post might be useful for this problem as well.
If your program is windows specific, you should see the following link:
https://stackoverflow.com/a/22074401/2724703
If your program is Gnu/Linux specific, you should see the following link:
https://stackoverflow.com/a/22085874/2724703
Program was programmed in C and compiled with GCC.
I was trying to help a friend who was trying to use trying to (shallow) copy a value that was passed into a function. His the value was a struct that held primitives and pointers (no arrays or buffers). Unsure of how malloc works, he used it similar to how the following was done:
void some_function(int rand_params, SOME_STRUCT_TYPEDEF *ptr){
SOME_STRUCT_TYPEDEF *cpy;
cpy = malloc(sizeof(SOME_STRUCT_TYPEDEF));// this line makes a difference?!?!?
cpy = ptr;// overwrites cpy anyway, right?
//prints a value in the struct documented to be a char*,
//sorry couldn't find the documentation right now
}
I told him that the malloc shouldn't affect the program, so told him to comment it out. To my surprise, the malloc caused a different output (with some intended strings) from the implementation with the malloc commented out (prints our garbage values). The pointer that's passed into the this function is from some other library function which I don't have documentation for at the moment. The best I can assume it that the pointer was for a value that was actually a buffer (that was on the stack). But I still don't see how the malloc can cause such a difference. Could someone explain how that malloc may cause a difference?
I would say that the evident lack of understanding of pointers is responsible for ptr actually pointing to memory that has not been correctly allocated (if at all), and you are experiencing undefined behaviour. The issue is elsewhere in the program, prior to the call to some_function.
As an aside, the correct way to allocate and copy the data is this:
SOME_STRUCT_TYPEDEF *cpy = malloc(sizeof(SOME_STRUCT_TYPEDEF));
if (cpy) {
*cpy = *ptr;
// Don't forget to clean up later
free(cpy);
}
However, unless the structure is giant, it's a bit silly to do it on the heap when you can do it on the stack like this:
SOME_STRUCT_TYPEDEF cpy = *ptr;
I can't see why there difference in the print.
can you show the print code?
anyway the malloc causes memory leak. you're not supposed to allocate memory for 'cpy' because pointer assignment is not shallow-copy, you simply make 'cpy' point to same memory 'ptr' point by storing the address of the start of that memory in 'cpy' (cpy is mostly a 32/64 bit value that store address, in case of malloc, it will store the address of the memory section you allocated)
I am using the code below to free up malloced memory in the meshes struct, which contains triangleArrays and faces.
This crashes because not every position in the struct has data. What I want to do is only call free if the struct contains data at that member of the array. However using if (self.meshes[meshIdx].triangleArrays[triangleArrayIdx].faces !=NULL) does not seem to work.
for (int meshIdx = 0; meshIdx <=meshTriangleArrays; meshIdx ++) {
for (int triangleArrayIdx = 0; triangleArrayIdx <=1; triangleArrayIdx ++) {
if (self.meshes[meshIdx].triangleArrays[triangleArrayIdx].faces !=NULL) {
free(self.meshes[meshIdx].triangleArrays[triangleArrayIdx].faces);
}
}
}
Calling free on a null pointer is actually fine.
You haven't given enough code to fully diagnose this problem, but a few things to look at:
You need to make sure that self.meshes[...].triangleArrays[...].faces is always initialized, either by a call to malloc (or whatnot), or by setting it to NULL. Otherwise it can (and likely will) be a random garbage pointer that you don't have permission to free.
You need to make sure that all the different self.meshes[...].triangleArrays[...].faces pointers are distinct pointers. You are only allowed to call free exactly once on a malloc'd pointer. For example, something like this:
int * p = (int *) malloc(sizeof(int));
free(p);
free(p); // undefined behavior
can cause a crash.
The below code crashes because not every position in the struct has data.
No, it doesn't crash due to passing a NULL pointer to free(). If you pass in a NULL pointer nothing happens, see the documentation.
What error is being thrown? Show us your initialization code as well, i.e., how are you allocating faces and everything above it? You are likely passing in some bad/uninitialized data to free().
BTW, due to the way you have asked this question I am lead to believe that you think simply declaring an array will fill every element with NULL. This is not the case, they may be filled with anything, and if you pass that to free you will crash (if you're lucky).
How was the triangleArrays array created in the first place? Is it possible that the non-allocated members contain garbage instead of NULL?
I'm using a struct like this:
define struct _Fragment{
int a;
char *seq;
}Fragment;
I want to initialize the struct, and using the malloc() method return a dynamic memory like this
Fragment *frag=malloc(10*sizeof(Fragment));
Then I would using the frag pointer like this:
frag->seq="01001";
Then the problem occurs when I returns a lot of Fragments. the error message said that (using valgrind tool):
Uninitialised value was created by a heap allocation
who can tell me how I can deal with it. thank you!
I'm not sure you have a real problem here, but for proper etiquette, your allocation would be:
Fragment *frag=malloc(10*sizeof(Fragment));
if (frag) memset(frag,0,10*sizeof(Fragment));
The problem is that even though you use malloc to allocate memory for a Fragment structure, you haven't initialized any of the values. The memory returned by malloc is not guaranteed to be any specific value so you must explicitly initialize the struct members
Fragment* frag = malloc(10*sizeof(Fragment));
int i = 0;
for ( i = 0; i < 10; i++ ) {
frag[i].a = 0;
frag[i].seq = NULL;
}
If you want guaranteed initialized memory you should use calloc. It has an added cost of zero'ing out the memory but it may not be significant for your app.
Also you should check that malloc actually succeeds :)
The issue is malloc does not initialize any of the memory it allocates. Valgrind takes particular care to keep track of any regions of memory that have not been initialized.
You should probably take heed of the error though, the only reason Valgrind (Assuming everything works correctly) should print that error is becuase you attempted to make use of the uninitialized data somewhere, which is probably unintended. The use of unitialized variables is not in the code you have in your question, however.
Your code looks plausible, but in the following line;
Fragment *frag=malloc(10*sizeof(Fragment));
Are you sure you need 10* ?
If you need to allocate 10 Fragments, then you should take responsibility for initializing all 10.