Accessing Arrays created Using Malloc - c

what is wrong with this?
why wont it work? its showing segmentation fault(core dumped)
Cant we use a[I]?
#include<stdio.h>
int main()
{
int *a,i,n;
scanf("%d",&n);
*a=malloc(n*sizeof(int));
for(i=0;i<n;i++)
a[i]=i;
free(a);
return(0);
}

Please enable compiler warnings; something should be screaming at you about:
*a=malloc(n*sizeof(int));
This says:
Allocate some memory.
Assign that address to the integer pointed to by a (which is uninitialized and points to no known location).
a itself is still pointing nowhere in particular.
Then:
a[i]=i;
writes into that random space.
You want to say:
a = malloc(n * sizeof(int));

*a = malloc( n * sizeof(int) ); should be a = malloc ( n * sizeof(int) );
malloc() allocates the storage and returns a pointer to the first byte.
As a is pointer variable is should point to the address.
Where as *a is incorrect in this case, because * along with pointers is used for de-referencing.

You are setting the memory address pointed to by a to the address returned by malloc. Since a is not yet initialized, you are setting an undefined part of memory to the address returned by malloc.
*a=malloc(n*sizeof(int));
Instead, set the pointer itself
a=malloc(n*sizeof(int));

Related

Allocating memory for one dimensional array in C

I have a question in regards to creating a dynamic array.
int *p;
p = malloc( 3 * sizeof( int ) );
// initializes elements in the array
for ( int i = 0; i < 3; ++i ) {
*p++ = i * 4;
}
how can i free the memory i just allocated? for some reason, i find much easier deallocating a two dimensional array than one LOL. It's been along time since the last time i used C.
if i do the following:
free( p ); // will probably get an error.
Another thing in regards to pointers. I tried this:
int * p = malloc( sizeof( int ) );
*p = 4;
printf( "%d\n", *p ) // prints 4 as expected
free( p );
printf( "%d\n", *p ) // still prints the number 4!!!
the free function should release the block of memory that p points to. how is it that printf stills prints 4 then?
Malloc() returns a pointer to the allocated block. Keep it for future use with free().
Index your array with integer OR walk through it with a pointer, but keep the original address stored somewhere.
You can do like this
int *p = malloc(3 * sizeof(int));
for( int i = 0; i < 3; i++)
p[i] = 4*i;
// .....
free(p);
or
int *p = malloc(3 * sizeof(int));
int *q = p;
for( int i = 0; i < 3; i++)
*q++ = 4*i;
// .....
free(p);
In the first case, you just write free(p) as you only allocated one block of memory.
What you are doing in the second case is undefined behaviour. It might print 4, it might crash, it could do literally anything. The chances are that the implementation is just marking that location as reusable, but not actually clearing it out (why should it, it's a waste of time)
free(p) de allocates memory pointed by p. But p still having memory address which is de allocated by free(p). De-allocation means that block of memory added to list of free memories which is maintained by memory allocation module. When you print data pointed by p still prints value at address because that memory is added to free list and not removed.
how can i free the memory i just allocated?
You could do something like this
int *p;
p = malloc( 3 * sizeof( int ) );
// initializes elements in the array
for ( int i = 0; i < 3; ++i ) {
p[i] = i * 4;
}
this would not change p, so you could use free(p) to free it.
If you need to change p, you should remember its original value in another variable, and call free() on that original value, such as
int *op;
op = p;
/* do something that changes `p` */
free(op);
how is it that printf stills prints 4
What you did, access a dynamically allocated memory region after you freed it, will lead to undefined behavior. It could print 4, it also could crash or do something really wild.
Malloc ==> Only allocate the memory (not changing memory data to NULL )
Free ==> Only It will release the allocated resources on the pointer,(not changing memory data to NULL )
In both cases user has the responsibly to set appropriate value if required.
In first case you can still free the memory by taking the pointer back to the first element's address and then calling free(p) like:
p = p-3;
free(p);
Reason : malloc store some information about how much memory need to be freed once allocated dynamically that's why you need to point it back to the start so that free can read that information and free exactly 3 int memory allocated by malloc.
In your second case it is still printing is not universal result, output can be anything even program may crash.
Reason : free do not do anything special with the memory it only add it back to the FREE LIST it maintains for the memory available for dynamic allocation.
It is only up-to the programmer that they do not dereference the after calling free on it.
how can i free the memory i just allocated?
When we want to free a memory chunk previously allocated by malloc(), we use the free function. This function accepts a char pointer to a previously allocated memory chunk, and frees it - that is, adds it to the list of free memory chunks, that may be re-allocated. Use free(p).
how is it that printf stills prints 4 then?
Usage Of free():
Several notes about free():
The size of the chunk was stored by malloc() previously in its memory map, and that is how free() knows how many bytes to free.
The freed memory is not being cleared or erased in any manner. This is why accessing memory that was just freed often does not cause a crash - any data in it is still the same as before calling free().
The free() function cannot nullify pointers to the given memory chunk that might still exist in our program. After we call free(), it is up to us (the programmers) not to try and dereference pointers that still point to that memory chunk. Such pointers are known as 'dangling pointers' - they point to memory that was already freed, and thus they should NOT be dereferenced again, unless they are assigned the address of a different (not-freed) memory chunk.

Allocating a value to a pointer in c

I am trying to give a value to a pointer.
this code works fine
int i =5;
int *ptr ;
ptr = &i;
printf(" %d\n",*ptr);
but this code shows an error
int i =5;
int *ptr ;
*ptr = 5;
printf(" %d\n",*ptr);
can someone explain this to me?
int *ptr gets initialized to a random location, which possibly points to invalid memory, and you try to write 5 to that location.
When you declare int *ptr, you're creating a variable called ptr which can hold the address of an int. When you dereference it in *ptr = 5, you're saying "store 5 in the address that ptr points to" - but as ptr is uninitialised, where it points to is undefined. So you're invoking undefined behaviour.
An int * does not store an int, but just an address that points to one. There still has to be a real int at that address.
If you want to allocate an int that exists outside of the local scope, you can use malloc. A simple conversion of your example without error checking:
int *ptr = malloc(sizeof(int));
*ptr = 5;
printf(" %d\n",*ptr);
If you do use malloc, just remember to free the allocated memory when you're finished:
free(ptr);
The second version assigns 5 to the memory pointed to by ptr, but you haven't yet initialized ptr to point to a known location.
So it writes the value to the memory at whatever address happens to be in ptr, which is whatever was in memory where ptr was declared.
You can't deterrence a pointer that doesn't point to somewhere you own.
int* ptr;
That allocates space for the pointer, but it doesn't allocate space for the chunk the pointer points to.
Also, since it's not initialized, ptr has an indeterminate value. This means that not only does it likely point to something you don't own, it also would be rather difficult to check if it's a valid pointer. It's usually a good idea to initialize pointers to either NULL (or nullptr if available) or an actual location (like you did in the first example).

Putting an int in an int pointer gives runtime error in C .

The following code works fine in ideone but it gives a runtime error in codeblocks IDE . Is my IDE broken or is there any programming language specific issues .
#include<stdio.h>
int main(){
int *pointer;
int num = 45;
*pointer = num;
printf("pointer points to value %d", *pointer);
return 0;
}
replace this
*pointer = num;
by
pointer = &num;
Your pointer should be pointed to a memory space before assignment of value to it.
When you define pointer in this way:
int *pointer;
This meas that you have defined pointer but the pointer is not yet pointing to a memory space. And if you use the pointer directly without pointing it to a memory space (like you did in your code) then you will get undefined behaviour.
pointing the pointer to amemory space could be done by one of the following way:
1) pointing to a static memory
int num;
int *pointer = &num;
num is an int defined as a static. So the pointer could be pointed to the num memory
2) pointing to a dynamic memory
int *pointer = malloc(sizeof(int));
the pointer could be pointed to a dynamic memory. the dynamic memory could be allocated with malloc() and when the memory became useless we can free memory with free(pointer)
Assign address of num to pointer as pointer is supposed to hold address not value. You can read more about pointers here
pointer = &num;
Change value of variable through pointer
*pointer = 11;
First,you have defined a pointer by "int *pointer".
Then, you try to use "*pointer = num" to realize indirect access —— assign num's value to the memory space which the pointer "pointer" has pointed to.
OK, here is the problem! From your codes, you only have defined a pointer, but you have not made it pointed to a memory space. Making indirect access without doing it is very dangerous. So, you see the runtime error.
Now, you should add "int value;pointer = &value;" to your codes. It will make the pointer "pointer" point to "value". And you can assign "num" to "value" through indirect access "*pointer = num".
In my opinion, you should distinguish definition and indirect access when you study pointer.
I'm a person with poor English. This is my first answer in stack overflow. I hope that my answer can help you. Thank you.
First of all u should initialize the pointer as to which its trying to point then use it to modify the pointed value..as...
pointer=&num;
now use the pointer to change or access the value to which its pointing.

Exact output of free() in C?

I wanted to ask, if I have a pointer pointing at some struct, but then I free(struct) then if I dereference the pointer, will it be pointing to NULL? As in can I check, pointer != NULL or is this undefined?
Thanks!
Calling free() on the pointer does not change the pointer value. It will still point to the same memory that no longer belongs to your application. You should always assign NULL to a free'd pointer immediately after you free it to ensure that you don't use it again.
void *p = malloc(10); // p points to allocated memory
free(p); // p still points to invalid memory
p = NULL; // good practice
Consider the below code
int main()
{
int *p = (int *)malloc(sizeof(int) * 10);
free(p);
}
Here variable p is a local variable of a function main. Size of this variable will be 4 bytes(in 32bit m/c) or 8 bytes(in 64 bit m/c). Now we are allocating memory for storing 10 integer elements and that address is stored in variable p. Now we are calling free function to which we are passing the dynamic memory address which is stored in the local variable p. Now free function will free the memory and it will not be able to assign NULL to the variable p. Because we passed address as value, not reference to the pointer.
We can define a wrapper function for free like below
void myfree(void **p)
{
free(*p);
*p = NULL;
}
int main()
{
int *p = (int *)malloc(sizeof(int) * 10);
myfree(&p);
}
Or we can define macro function also
#define MYFREE(x) \
free(x); \
x = NULL;
It's undefined. C does not define what it does with the contents of the pointer, although most implementations do nothing.
Take a look at this page.
It clearly says:
Notice that this function leaves the value of ptr unchanged, hence it
still points to the same (now invalid) location, and not to the null
pointer.
Note that it is up to you to make sure that pointer is not dereferenced after being freed.

Passing pointers with space allocated by malloc

I've just written a function that returns a pointer to a block of memory allocated by malloc. If I call free() on the returned pointer, will this free the memory?
I tried reading up on this, but I can't find anything that says whether you can call a different pointer pointing to the same location and whether that will free all the memory or not.
This is probably majorly basic, I think I can't find the info because I'm searching for it wrong.
Any help appreciated!
Yes calling free will free the memory. Its not the pointer that get freed but the memory that the pointer points to that is freed.
You must pass to free() the value obtained from malloc().
int *x = malloc(42 * sizeof *x);
int *p = &x[0];
free(p); /* ok, same as free x; x and p have the same value */
Edit: another example
int *x = malloc(42 * sizeof *x);
for (k = 0; k < 24; k++) *x++ = 0; /* zero first 24 elements */
free(x - 24);
It's not entirely clear what you're asking here, but if what you're asking is:
Can I call free() on a pointer which points to a location within the allocated block?
then the answer is "no" -- you must pass free() the exact pointer which you got back from malloc(). Trying to free() an internal pointer, or a pointer to memory which was not allocated by malloc(), memory corruption or a crash are likely to occur.

Resources