Using free on structure which contains unintialized pointer - c

I have structure with an integer and character pointer. I am just allocation memory for the structure. Now if try to free the same structure, pointer will also be freed?
struct a
{
int b;
char *c
};
main()
{
struct *d = malloc(sizeof(a));
free(d);
}
There is no memory leak in above programm?

In order for there to be a memory leak, there has to be something that was allocated that can no longer be referenced. Since the only thing allocated here is what was explicitly freed, there was no leak.
The fact that you have a pointer in the structure is irrelevant, since you never allocated anything for it to point to.

Related

Can't I directly put head=NULL if i want to destroy linked list and free memory?

Why do we need free()? Putting the head node as NULL does similar work, doesn't it?
Why do we need free()?
The function free is used to free a dynamically allocated memory.
Putting the head node as NULL does similar work, doesn't it?
Putting NULL in the pointer to the head node does not free all dynamically allocated memory in the list neither for the head node nor for other nodes. This leads to loosing the address of the first dynamically allocated node and as a result you will get numerous memory leaks because the memory becomes inaccessible (but not freed)..
Consider the following demonstrative program.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int *p1 = malloc( sizeof( int ) );
*p1 = 10;
printf( "*p1 = %d\n", *p1 );
int *p2 = p1;
p1 = NULL;
printf( "*p2 = %d\n", *p2 );
free( p2 );
return 0;
}
Its output is
*p1 = 10
*p2 = 10
In the program there is dynamically allocated a memory for an object of the type int and the address of the allocated memory was assigned to the pointer p1.
After assigning NULL to the pointer p1 the address of the allocated memory is not stored in this pointer any more.
So if the address was not assigned to the second pointer p2 then the address of the allocated memory would be lost forever and we could not free the memory.
Only due to having a copy of the address in the pointer p2 we can free the allocated memory.
Thus setting a pointer to NULL only changes the value stored in the pointer. The allocated memory is not touched in any way.
They are not equivalent.
In C, if you explicitly allocated memory (e.g., by using malloc), you need to explicitly free it (by using free).
If you just assign head = NULL, you won't be able to access the following elements in the linked list, but their memory will still be allocated - the process will still hold this memory, and you'll have a memory leak on your hand.
Because there is no garbage collector in C. This means you should collect your garbage yourself.
Everything you allocated on the heap has to be deleted manually.
Forgetting to do it is called memory leak.

Can I free memory originally allocated from another pointer?

If I allocated memory from another pointer, then declare a pointer equal to the other pointer, can I then free the memory allocated with the first pointer by using free() on the new pointer?
Example:
typedef struct foo{
int n;
char c;
} foo;
foo* bar = malloc(sizeof(foo));
foo* tmp = bar; // declaring pointer identical to other pointer
free(tmp); // can I do this to free *bar?
Yes, it is completely fine.
Your implementation of malloc will most likely mark the chunk of memory as allocated before returning a pointer to it.
Now you can have as many pointer variables as you want which point to this chunk of memory and you can free that memory by calling free on any of them.
The pointer itself doesn't contain information about whether the memory it points to has been allocated. It just points to it.
int* i = malloc(sizeof(int) * 23);
int* j = i;
free(j);
// free(i); // this is undefined behavior, the memory was already freed
Yes you can do what you are asking about. But it is not another pointer, what you are freeing is the same pointer. When malloc returns a pointer, it is essentially giving you an integer that is the address of the start of the chunk of memory that it has reserved for you. When you are done are done with the memory, you pass that address to free. As far as free is concerned, there is no difference between:
free(malloc(17));
,
void *p = malloc(17);
free(p);
or
void *p1 = malloc(17);
void *p2 = p1;
free(p2);
In all of these cases the value returned from malloc is getting to free, and that is all that matters.

malloc allocate memory to a non-pointer type

How to allocate memory to a type which is not a pointer ?
I'd searched on the Internet and my textbook then got nothing about this.
All the example come from those like that
char *test;
test = malloc (STRING_SIZE * sizeof (char));
Which in pointer form, but what if a structure don't even need a pointer type to do that job as follow
struct _test_t {
char *name;
int flag; // <-- Here
};
or this is deprecated ?
What I can do is only declare as a pointer
...
int *flag;
...
then allocate as usual ?
struct _test_t *t;
t->flag = malloc (sizeof (int));
or any way out ?
You seem to have some confusion about pointers and where things end up in memory. The fields of a struct are part of the struct's memory. In your case, the struct consists of a char pointer and an int. You don't need to allocate those separately once you have an instance of the struct, because they are already part of the struct.
struct _test_t *t = malloc(sizeof(struct _test_t));
t->flag = 123;
t->name = NULL;
Note that name doesn't point to anything interesting yet. Let's change that:
t->name = malloc(100);
Note the distinction between the pointer name and the memory that it points to. Only the pointer itself is part of the struct.
It is also possible to create an instance of the struct without using malloc, by allocating it on the stack:
struct _test_t t;
t.flag = 123;
t.name = malloc(100);
t is now allocated on the stack and will automatically be freed again when you leave the scope that it was declared in. However, name still points to memory on the heap which does not get freed with the struct, so you'd have to free that manually once you no longer need it.
Edit: You mention that you want to allocate memory to something that is not a pointer. That doesn't really make sense to me though. The function of malloc is to reserve some memory for your use and return a pointer to that memory. It needs to return the address of the memory that it has allocated because otherwise you wouldn't know where it is. And a pointer is really just an address value.
You can allocate space for an int with malloc, but you will get a pointer to an int that you have to use to access the actual int:
int *i = malloc(sizeof(int));
*i = 123;
In C, there is no way to refer to that int directly without going through a pointer, which might be what you want. In C++ you could use a reference to refer to the int value directly:
int *i = (int*)malloc(sizeof(int));
*i = 123;
int &j = *i;
cout << j << endl;
This would print "123", showing that j directly refers to the integer value. However, C does not have that feature, so you will always have to use the pointer.
malloc is used to allocate memory for objects whose size is not known at compile-time. That's why it returns a pointer, since it's the C representation for addresses (here of the memory area allocated on the heap).
Using malloc for another type does not make any sense, since their size are known (apart from templates but that's C++). Your _test_t struct (resp struct _test_t *t) is allocated resp. on the stack or the heap when declared, no need for you to manually allocate each members.

Difference between dangling pointer and memory leak

I don't understand the difference between a dangling pointer and a memory leak. How are these two terms related?
A dangling pointer points to memory that has already been freed. The storage is no longer allocated. Trying to access it might cause a Segmentation fault.
Common way to end up with a dangling pointer:
char *func()
{
char str[10];
strcpy(str, "Hello!");
return str;
}
//returned pointer points to str which has gone out of scope.
You are returning an address which was a local variable, which would have gone out of scope by the time control was returned to the calling function. (Undefined behaviour)
Another common dangling pointer example is an access of a memory location via pointer, after free has been explicitly called on that memory.
int *c = malloc(sizeof(int));
free(c);
*c = 3; //writing to freed location!
A memory leak is memory which hasn't been freed, there is no way to access (or free it) now, as there are no ways to get to it anymore. (E.g. a pointer which was the only reference to a memory location dynamically allocated (and not freed) which points somewhere else now.)
void func(){
char *ch = malloc(10);
}
//ch not valid outside, no way to access malloc-ed memory
Char-ptr ch is a local variable that goes out of scope at the end of the function, leaking the dynamically allocated 10 bytes.
You can think of these as the opposites of one another.
When you free an area of memory, but still keep a pointer to it, that pointer is dangling:
char *c = malloc(16);
free(c);
c[1] = 'a'; //invalid access through dangling pointer!
When you lose the pointer, but keep the memory allocated, you have a memory leak:
void myfunc()
{
char *c = malloc(16);
} //after myfunc returns, the the memory pointed to by c is not freed: leak!
A dangling pointer is one that has a value (not NULL) which refers to some memory which is not valid for the type of object you expect. For example if you set a pointer to an object then overwrote that memory with something else unrelated or freed the memory if it was dynamically allocated.
A memory leak is when you dynamically allocate memory from the heap but never free it, possibly because you lost all references to it.
They are related in that they are both situations relating to mismanaged pointers, especially regarding dynamically allocated memory. In one situation (dangling pointer) you have likely freed the memory but tried to reference it afterwards; in the other (memory leak), you have forgotten to free the memory entirely!
Dangling Pointer
If any pointer is pointing the memory address of any variable but after some variable has deleted from that memory location while pointer is still pointing such memory location. Such pointer is known as dangling pointer and this problem is known as dangling pointer problem.
#include<stdio.h>
int *call();
void main(){
int *ptr;
ptr=call();
fflush(stdin);
printf("%d",*ptr);
}
int * call(){
int x=25;
++x;
return &x;
}
Output: Garbage value
Note: In some compiler you may get warning message returning address
of local variable or temporary
Explanation: variable x is local variable. Its scope and lifetime is within the function call hence after returning address of x variable x became dead and pointer is still pointing ptr is still pointing to that location.
Solution of this problem: Make the variable x is as static variable.
In other word we can say a pointer whose pointing object has been deleted is called dangling pointer.
Memory Leak
In computer science, a memory leak occurs when a computer program incorrectly manages memory allocations.
As per simple we have allocated the memory and not Free other language term say not release it call memory leak it is fatal to application and unexpected crash.
Pointer helps to create user defined scope to a variable, which is called Dynamic variable. Dynamic Variable can be single variable or group of variable of same type (array) or group of variable of different types (struct). Default local variable scope starts when control enters into a function and ends when control comes out of that function. Default global vairable scope starts at program execution and ends once program finishes.
But scope of a dynamic variable which holds by a pointer can start and end at any point in a program execution, which has to be decided by a programmer. Dangling and memory leak comes into picture only if a programmer doesnt handle the end of scope.
Memory leak will occur if a programmer, doesnt write the code (free of pointer) for end of scope for dynamic variables. Any way once program exits complete process memory will be freed, at that time this leaked memory also will get freed. But it will cause a very serious problem for a process which is running long time.
Once scope of dynamic variable comes to end(freed), NULL should be assigned to pointer variable. Otherwise if the code wrongly accesses it undefined behaviour will happen. So dangling pointer is nothing but a pointer which is pointing a dynamic variable whose scope is already finished.
Memory leak: When there is a memory area in a heap but no variable in the stack pointing to that memory.
char *myarea=(char *)malloc(10);
char *newarea=(char *)malloc(10);
myarea=newarea;
Dangling pointer: When a pointer variable in a stack but no memory in heap.
char *p =NULL;
A dangling pointer trying to dereference without allocating space will result in a segmentation fault.
A pointer pointing to a memory location that has been deleted (or freed) is called dangling pointer.
There are three different ways where Pointer acts as dangling pointer.
De-allocation of memory
Function Call
Variable goes out of scope
—— from https://www.geeksforgeeks.org/dangling-void-null-wild-pointers/
A pointer pointing to a memory location that has been deleted (or freed) is called dangling pointer.
#include <stdlib.h>
#include <stdio.h>
void main()
{
int *ptr = (int *)malloc(sizeof(int));
// After below free call, ptr becomes a
// dangling pointer
free(ptr);
}
for more information click HERE

Where are character arrays in dynamically allocated structs stored? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C Array Instantiation - Stack or Heap Allocation?
When dynamically allocating a struct containing a char pointer, what happens with the actual char pointer? Where is it stored?
And once the struct is freed, is the char pointer freed along with it?
For example consider the following struct:
struct mix
{
int a;
float b;
char *s;
};
typedef struct mix mix;
And then the following code that allocates memory for it:
int main()
{
mix *ptr = (mix*)malloc(sizeof(mix));
ptr->a = 3;
ptr->b = 4.5f;
ptr->s = "Hi, there, I'm just a really long string.";
free(ptr);
return 0;
}
Is *s allocated on the stack and then freed along with *ptr? I can imagine it is indeed allocated on the stack as it's not in any way dynamically allocated (unless malloc has some functionality I'm not aware of). And I guess 'going out of scope' for *s would be at the point of freeing *ptr. Or have I got it completely wrong? :)
Thanks very much!
The space for the char* member named s is allocated on the heap, along with the rest of the members of mix after the call to malloc() (whose return value you do not need to cast). The string literal to which s is assigned is not allocated on the heap or the stack, but is part of the actual binary and has static storage duration. So this:
ptr->s = "Hi, there, I'm just a really long string.";
assigns the address of the string literal to ptr->s. If you want ptr->s to point to something other than a string literal then you need to malloc() memory for it. And for every malloc() there must be a free() so ptr->s would need to be free()d before ptr is (if ptr->s is pointing to dynamically allocate memory only).
After the call to free(), dereferencing ptr is undefined behaviour.
When you dynamically allocate mix with malloc(), you are actually allocating a block of memory to store mix structure data members, i.e.
an int (a)
a float (b)
a pointer to a char (s)
And when you call free(), you just release that block.
So, you don't allocate the string, you just allocate the string pointer.
If you want to dynamically allocate the string, you must do it explicitly (with another call to malloc()), and to avoid memory leaks you should also free the string explicitly, using free().
When you malloc for ptr, memory is allocated for all members of the struct including the pointer s which is no different to memory allocated for any other member of the struct.
You are assigning a string literal to s, so it's fine which is usually stored in the read-only section. Otherwise, you'll need to malloc for the ptr->s as well and free. Since, it's a string literal, there's no need to free s here (doing so is UB).
mix* ptr is allocated on the stack. The contents that ptr point at, a variable of type mix, is allocated dynamically on the heap, including the pointer s.
Please note that s doesn't point at anything, the pointer doesn't do anything useful. You have to set it to point at something, which could be allocated anywhere. Whatever it points to is not freed when your struct is freed. In this case you set it to point at a constant string literal allocated in ROM, so you won't need to worry about that.
Is *s allocated on the stack
*s (that is, the result of dereferencing the pointer s) isn't allocated at all. Following the malloc, ptr->s is an uninitialized pointer. It doesn't point to anything, and the expression *(ptr->s) has undefined behavior until you do ptr->s = "Hi, etc".
Once you've initialized ptr->s to point to the string literal, *(ptr->s) is the first character of the string literal, so it probably exists in some data section of the executable. Nothing is dynamically allocated other than the sizeof(mix) bytes for the struct (probably 12 bytes on a 32bit implementation).
what happens with the actual char pointer? Where is it stored?
char* is also like other members, take some bytes(take 8 byte in 64 bit machine, similar to other pointer). In your case, you are allocating memory for that structure instance in heap. so the memory for this pointer also will be allocated in same heap block which is allocated for that structure instance.
Consider this code. This gives where the char* will be:
#include <stdio.h>
typedef struct
{
int a;
float b;
char *s;
}mix;
int main()
{
printf("\n%d ,float:%d, int:%d, char*:%d", sizeof(mix), sizeof(float), sizeof(int), sizeof(char*));
return 0;
}
so size of this structure is 16 bytes. consist of 4 byte integer, 4 byte float and 8 byte char*. (In 64 bit OS, char* will be 4 bytes if OS is 32 bit.)
And once the struct is freed, is the char pointer freed along with it?
Usually the block which is pointed by char* will not be freed(If it points to a block allocated by malloc()). only the structure block will be freed. we know free() needs valid address which is returned during allocation for peaceful de-allocation. If you free without freeing that char*, it will leads to memory leak.
But your case "Hi, there, I'm just a really long string.";
the above given string is string literal which is allocated in read-only section of your program.
use gcc -S Yourprogram.c
This will generate .s file. You can look at .read_only section for this string. so even you delete your structure instance, there will be no memory leak. Because you are just pointing a address which is read-only. You are not at-all allocating memory for this string.

Resources