Why am I receiving invalid pointer error when running this code - c

I am receiving the following error when running this code.
Error in `main': free(): invalid pointer:
My idea is to use a pointer allocated through malloc. This is a sample code.
Please let me know why I am receiving this error.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int c=10;
int* ptr = NULL;
ptr = (int*)malloc(sizeof(int));
if(ptr == NULL)
{
printf("Memory not allocated");
exit(0);
}
ptr = &c;
free(ptr);
ptr=NULL;
}

int c=10;
Variable c allocated on the stack.
ptr = (int*)malloc(sizeof(int));
Assign address of allocated memory on the heap to ptr
ptr = &c;
Assign address of c to ptr.
You have two problems in your code.
Memory Leak. You have lost address of allocated memory since you used reassign of ptr. In this case you don't have any other way to free memory allocated on the heap until program ends.
You can't free memory allocated on the stack with free() function. It's auto variables
So, If you were trying to assign the value of c to the allocated space:
*ptr = c;

Why am I receiving an invalid pointer error?
Because you free a pointer that was not allocated with malloc (or realloc).
You have a memory leak, i.e. you lose a malloced pointer with ptr = &c, which assigns the address of c to ptr, losing the value returned by malloc.

Well to do that you need to allocate for a pointer of pointer like this
#include <stdio.h>
#include <stdlib.h>
int main() {
int c=10;
int** ptr = NULL;
ptr = (int**)malloc(sizeof(int*));
if(ptr == NULL)
{
printf("Memory not allocated");
exit(0);
}
*ptr = &c;
free(ptr);
ptr=NULL;
}
the problem in your case that you are freeing a non dynamic allocated memory and that gives you an error, and even in other cases you should always keep the address of the allocated memory to free it when you no more need it for example
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr1 = (int*)malloc(sizeof(int));
int *ptr2 = (int*)malloc(sizeof(int));
*ptr1 = 5;
*ptr2 = 10;
// this is wrong because now there is no way to free
// the address of the allocated memory to ptr1
ptr1 = ptr2;
free(ptr1);
// this gives an error because ptr2 is already free
free(ptr2);
}
Conclusion:
If you want to allocate to store a pointer, then you need to allocate for a pointer to pointer, so the pointer of the allocated memory stay so you can free that memory when you no longer need it

Related

How can I use realloc function without discarding the old memories

First of all, I'm sorry for my bad English.
I have a question about 'realloc' function in language C.
I thought it allocates memories with given length.
When the memories ain't enough for the given length, it copies whole memories to another memory pointer and returns it.
I wanted to use realloc function with preserving the old memories.
So I sentenced another pointer and made it pointing at the old memories.
But whenever 'realloc' function works, it frees the old memories.
How can I preserve old memories?
In addition, I want to know why this is happenend.
the below is code and its result I've used for testing realloc function.
#include <stdio.h>
#include <stdlib.h>
int* ptr1, lenPtr1;
int* ptr2;
void double_ptr1(){
lenPtr1 *= 2;
ptr1 = (int*)realloc(ptr1, sizeof(int) * lenPtr1);
}
void print(){
printf("ptr1 -> %p, *ptr1 = %d\n", ptr1, *ptr1);
printf("ptr2 -> %p, *ptr2 = %d\n", ptr2, *ptr2);
printf("\n");
}
int main(){
lenPtr1 = 10;
ptr1 = (int*)malloc(sizeof(int) * lenPtr1);
ptr2 = ptr1;
*ptr1 = 10;
print();
double_ptr1();
print();
system("pause");
return 0;
}
ptr1 -> 0108D2F0, *ptr1 = 10
ptr2 -> 0108D2F0, *ptr2 = 10
ptr1 -> 00FF5740, *ptr1 = 10
ptr2 -> 0108D2F0, *ptr2 = -17891602
An example incorporating all improvements suggested in the comments and avoiding the use of global variables, and freeing all allocated memory before the program exits. There is only a need to hold the terminal window open on windows, so conditionally enclose the system("pause");.
Putting it altogether, you would have:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int *double_ptr (int *ptr, int *ptrsz) /* pass needed information as parameters */
{
int *newptr = malloc (2 * *ptrsz * sizeof *newptr); /* allocate new block of mem */
if (newptr) { /* validate allocation */
memcpy (newptr, ptr, *ptrsz * sizeof *ptr); /* copy to new block of mem */
*ptrsz *= 2; /* update allocated size */
}
return newptr; /* return pointer */
}
void print (int *ptr1, int *ptr2) /* pass needed information as parameters */
{
/* only one call to printf required */
printf ("ptr1 -> %p, *ptr1 = %d\nptr2 -> %p, *ptr2 = %d\n\n",
(void*)ptr1, *ptr1, (void*)ptr2, *ptr2);
}
int main (void) {
int *ptr1 = NULL, *ptr2 = NULL, lenPtr1 = 10; /* avoid global variables */
if (!(ptr1 = malloc (lenPtr1 * sizeof *ptr1))) { /* validate EVERY allocation */
perror ("malloc-ptr");
return 1;
}
ptr2 = ptr1; /* pointer 1 and 2 hold same address where 10 is stored in memory */
*ptr1 = 10;
printf ("lenPtr1: %d\n", lenPtr1); /* output len, addresses, values */
print (ptr1, ptr2);
if (!(ptr1 = double_ptr (ptr1, &lenPtr1))) { /* double size of ptr1 */
perror ("malloc-double-ptr1");
return 1;
}
printf ("lenPtr1: %d\n", lenPtr1); /* output len, addresses, values */
print (ptr1, ptr2);
free (ptr1); /* free allcoated memory */
free (ptr2);
#if defined (_WIN32) || defined (_WIN64)
system("pause");
#endif
}
Example Use/Output
$ ./bin/doubleptrsz
lenPtr1: 10
ptr1 -> 0xb18260, *ptr1 = 10
ptr2 -> 0xb18260, *ptr2 = 10
lenPtr1: 20
ptr1 -> 0xb186a0, *ptr1 = 10
ptr2 -> 0xb18260, *ptr2 = 10
Let me know if you have further questions.
When you realloc the original pointer, which is pointed by ptr2, the address of the original pointer is removed.
So after you realloc the ptr1, ptr2 points address that does not exists anymore.
If you want to preserve old memory, then you just need to malloc(or calloc) new memory to ptr1 with no realloc original one.
When the memories ain't enough for the given length, it copies whole memories to another memory pointer and returns it.
Not quite. realloc always deallocates the old memory. It may return the same pointer.
From C11 7.20.3.4 realloc...
The realloc function deallocates the old object pointed to by ptr and returns a pointer to a new object that has the size specified by size.... The realloc function returns a pointer to the new object (which may have the same value as a pointer to the old object)
I wanted to use realloc function with preserving the old memories.
You can't.
If you need more memory, malloc a new hunk of memory instead of reallocing the old one.
If you want to shrink memory, continue to use the memory as is. It'll work fine, it's just a waste of memory.
I'd recommend neither. Instead, redesign whatever you're doing so the pointer is accessed indirectly. Perhaps using a pointer to a pointer. Or put the pointer inside a struct and pass around a pointer to the struct.
Alternatively, redesign it so you do not need to realloc. For example, when reading from a file use a fixed size buffer to read the line and then copy that to memory with exactly enough space.
// A large buffer to reuse for each line.
char buf[BUFSIZ];
while( fgets(buf, sizeof(buf), fp) ) {
// Allocate exactly enough space for the line.
// In reality, use strdup.
char *string = malloc(strlen(buf) + 1);
strcpy(string, buf);
}
Or change to a data structure which does not rely on a single block of memory. For example, a linked list instead of an array.
In addition, I want to know why this is happened.
There are many implementations of malloc, but they all must allocate contiguous blocks of memory with no overlap.
Consider two calls to malloc.
char *foo = malloc(8);
char *bar = malloc(8);
And let's say foo and bar are allocated adjacent blocks of memory like so. (Note: there's no guarantee they will be adjacent and many reasons why they shouldn't be.)
0123456789abcdef0123456789abcdef
^^^^^^^^
| ^^^^^^^^
foo |
bar
Now you try to grow foo.
foo = realloc(foo, 16);
If realloc tries to keep the same pointer, foo would have to overlap into bar's memory.
0123456789abcdef0123456789abcdef
^^^^^^^^^^^^^^^^
| ^^^^^^^^
foo |
bar
That's not allowed, allocations cannot overlap. They also must be contiguous, so it cannot do this:
0123456789abcdef0123456789abcdef
^^^^^^^^ ^^^^^^^^
| ^^^^^^^^
foo |
bar
If it were allowed to do that, pointer math would not work. You would not be able to reliably add to foo to walk through its allocated memory.
So realloc must free foo and allocate a new block. (Again, no guarantee where it will be allocated.)
0123456789abcdef0123456789abcdef
^^^^^^^^
| ^^^^^^^^^^^^^^^^
bar |
foo

free() : invalid pointer and how to reuse a currently freed pointer

I want to address my pointer to another object and free the memory of previous object. This is what I did but I had a invalid pointer error. What is the right way to do it?
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
int number = 5;
int number2 = 10;
// Give memory manually
int *pointer2number = (int *) malloc(sizeof(int));
pointer2number = &number;
printf("Number is %i\n", number);
printf("Address of number is %p\n", pointer2number);
// Free memory
free(pointer2number);
pointer2number = (int *) malloc(sizeof(int));
pointer2number = &number2;
printf("New number is %i\n", *pointer2number);
return 0;
}
int *pointer2number = (int *) malloc(sizeof(int));
pointer2number = &number;
You assign the address of number to the pointer pointer2number and with that replace the address of the allocated dynamic memory stored in pointer2number before.
The same goes for the second attempt with number2.
Any attempt to free() a memory not previously allocated by a memory-management function, invokes undefined behavior:
"The free function causes the space pointed to by ptr to be deallocated, that is, made available for further allocation. If ptr is a null pointer, no action occurs. Otherwise, if the argument does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined."
Source: ISO/IEC 9899:2018 (C18), Section 7.22.3.3/2
And as side-effect, the previously allocated dynamic memory isnĀ“t free()d with that too.
Overthink the logic of your program!

Why cannot be pointer free() after pointing to string literal

There are some related discussions about my problem but there are no clearly explanations about my problem.
I thought that I must free() whatever I malloc(), no matter when or where but I have to do it, to prevent a memory leak.
So i have the following program:
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int *ptr;
ptr = malloc(256);
if (ptr == NULL) {
printf("Out of memory\n");
return 1;
}
*ptr = 10;
printf("The value of PTR is:\t%d\n",*ptr);
free(ptr);
return 0;
}
I have a pointer and I dynamically allocated some memory (256), then I checked for NULL letter I free() it.
Until here everything is OK: to the pointer was dynamically allocated some memory and then I free() it.
Now i will use a char pointer this time and after i will dynamically allocated some memory (256), i will point that pointer to a string literal, lets say MICHI:
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
char *ptr;
ptr = malloc(256);
if (ptr == NULL) {
printf("Out of memory\n");
return 1;
}
ptr = "michi";
printf("%s",ptr);
free(ptr);
return 0;
}
Here I am doing something wrong because if i try to free() it, well it will not work because it happens that i'm going to free a non-heap object.
So i'm lost in here, because i thought that everything you malloc() you have to free() it.
What exactly make that pointer, after points to a string literal, to not need to be free()ed
ptr = malloc(256);
...
ptr = "michi";
printf("%s",ptr);
free(ptr);
As you allocate memory to ptr and then you make it point to string literal. Thus pointer ptr no longer points to memory allocated by malloc.
And to free memory not allocated by malloc or similar functions cause error in program.
Do this instead:
strcpy(ptr,"michi");
In the first program you allocated memory
ptr = malloc(256);
and initialized its first sizeof( int ) bytes with integer value 10.
*ptr = 10;
The pointer itself was not changed. So in this statement
free(ptr);
pointer ptr points to the memory that was allocated using malloc.
In the second program you allocated memory the same way as in the first program
ptr = malloc(256);
But then you reassigned the pointer itself with the address of the first character of string literal "michi"
ptr = "michi";
Compare the left sides of this assignment
*ptr = 10;
and of this assignment
ptr = "michi";
As you see they are different. In the first case you are changing the allocated memory while in the second case you are changing the pointer itself.
Thus in this statement
free(ptr);
pointer ptr does not point to the memory that was previously allocated. It points to the memory occupied by the string literal that was not allocated using malloc.
Thus this statement is wrong and the program has a memory leak because the previous memory that was allocated using malloc was not freed,
Because constant literals are stored in a way for the lifetime of the program, in a read-only region of memory in most of the platforms.
When you use free you are trying to free the memory allocated, not the pointer itself, that's why it's not gonna work if you try to do that in a read-only region of memory
When you reassign your pointer you're losing track of the allocated memory and therefore creating a memory leak.
The memory leak is created because you first allocated the memory and assign it to your pointer, when you've a pointer pointing to it you can easily free that memory, but when you don't have any more reference to that memory you can't.
That's what's happening, when assign the literal to the pointer there's no more reference to that address, it was allocated but it's not reachable anymore, in this way you can't free the memory.
The problem is that you have lost the pointer the second you assigned another value to it:
ptr = malloc(256);
if (ptr == NULL) {
printf("Out of memory\n");
return 1;
}
// here you should free your memory
ptr = "michi";
printf("%s",ptr);
// this fails, because ptr now points to the const static string "michi" you have coded yourself. The assignment didn't copy it, just changed what ptr points to.
free(ptr);
Try this.
#include <stdio.h>
int main(void)
{
char *str:
str = (char*)malloc(sizeof(str) * 4);
printf("Addr of str before: %p\n", str);
str = "Joe";
printf("Addr of str after: %p\n",str);
return(0);
}
/* you will get the following addresses:
Addr of str before: 0x51fc040
Addr of str after: 0x4006f0
this is becuase you changed where str points to. 0x51fc040 is memory allocated using malloc and 0x4006f0 is the memory Adress of the string literal "Joe".
I would advice the following...*/
#include <stdio.h>
int main(void)
{
char *str;
str = (char*)malloc(sizeof(str) * 4);
printf("Addr of str before: %p\n", str);
str =strncpy(str, "Joe", 4);
printf("Addr of str after: %p\n",str);
free(str);
return (0);
}
/* you will get the following addresses:
Addr of str before: 0x51fc040
Addr of str after: 0x51fc040
This is because strncpy copies the string literal to the memory dynamically allocated. and it is safer than stcpy, since it prevents buffer overflow

Pointers and malloc.... Wrong in this code snippet

#include <stdio.h>
#include <stdlib.h>
int main()
{
int *ptr = NULL;
ptr = (int*)malloc(2*sizeof(int*));//memory allocation dynamically
return 0;
}// What is the error in this type of allocation
I guess you want allocate the space for 2 ints (not 2 pointers to int):
int *ptr = malloc(2*sizeof(int));//memory allocation dynamically
You would have understood that if you read the compilation error carefully.
int *ptr = NULL;
ptr = (int*)malloc(2*sizeof(int*)); //wrong
The above code is wrong. It should be:
ptr = malloc(2*sizeof(*ptr));
No need to cast the return value of malloc. void * will be safely casted. Additionally, using sizeof(*ptr) is easier to maintain in case ptr's data type needs to be modified.
Also, free dynamically allocated memory when its no longer needed or you will have memory leak.
free(ptr);
The problem lies at sizeof(int*)) and it should be sizeof(int))
Dynamic allocation requires you to tell what size of bytes you want it to allocate, and for that reason in this example you should use sizeof(int).

C - dynamic memory allocation using double pointer

I am allocating some memory in a function name myalloc() and using and freeing it in main().
I am using double pointer to do this, here is the code which works fine,
//Example # 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void myalloc( char ** ptr)
{
*ptr = malloc(255);
strcpy( *ptr, "Hello World");
}
int main()
{
char *ptr = 0;
myalloc( &ptr );
printf("String is %s\n", ptr);
free(ptr);
return 0;
}
But following code does not work and gives segmentation fault.
I think this is another way to use double pointers.
//Example # 2
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void myalloc( char ** ptr)
{
*ptr = malloc(255);
strcpy( *ptr, "Hello World");
}
int main()
{
char **ptr = 0;
myalloc( ptr );
printf("String is %s\n", *ptr);
free(*ptr);
return 0;
}
Please clarify me, why it is giving me seg fault in second example.
Note: Language = C, Compiler = GCC 4.5.1, OS = Fedora Core 14
Also, i know that there are some question already been asked related to memory allocation using double pointers, but they don't address this issue, so please don't flag it as repetitive question.
char **ptr = 0;
*ptr = malloc(255);
tries to write the pointer returned by malloc to the address(of type char*) pointed to by ptr. The address turns out to be ... 0, which is not writable memory.
ptr should point to an address you can write to. You can do one of the following:
char *stackPtr; // Pointer on the stack, value irrelevant (gets overwritten)
ptr = &stackPtr;
// or
char **ptr = alloca(sizeof(char*)); // Equivalent to above
// or
char **ptr = malloc(sizeof(char*)); // Allocate memory on the heap
// note that ptr can be 0 if heap allocation fails
char **ptr = 0;
foo( ptr );
You are passing the value that ptr points to. But you havent pointed ptr to anything yet.
*ptr = malloc(255);
Now you are assigning some memory to that "nothing". So this wont work, and will segfault.
Why are you saying that this is another way of using double pointers? I apologise if I am wrong, but I guess you worked with type of program in Turbo-C earlier?
In the second case, you are passing the value of main's ptr, which is 0 (NULL), to myalloc()'s ptr. myalloc() then tries to dereference its null pointer, ptr.

Resources