#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).
Related
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
this is just a test code i've been using to figure out how the code works before impelmenting it into my program. basically the same issue happens in both programs, im able to realloc 2 times then it crashes. the final project is a 2d pointer, list length and size lengths. ach of these has to be able to be resized to reasonable limits.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char** tasks;
char buff[1089];
int size, i, list_size=1;
tasks = (char**)malloc(list_size * sizeof(char*));
printf("input a string!\n");
gets(buff);
*tasks[0]=(char*)malloc((strlen(buff)+1));
tasks[0]=buff;
printf("%s\n", tasks[0]);
for (i=1;i<8 ;i++){
list_size++;
printf("%d\n", list_size);
*tasks = realloc(*tasks, list_size* sizeof(char*));
printf("input a string!\n");
gets(buff);
*tasks[i]=(char*)malloc((strlen(buff)+1));
tasks[i]=buff;
printf("%s\n", tasks[i]);
}
free(tasks);
return 0;
}
what am i messing up with here?
Several problems here.
*tasks[0]=(char*)malloc((strlen(buff)+1));
As pointed out by David Heffernan in the comments, you are assigning a pointer to a char. You probably just meant to assign to tasks[0].
tasks[0]=buff;
This is not how you copy a string. You're setting tasks[0] to point to your fixed buffer, and leaking the memory you allocated in the previous step.
*tasks = realloc(*tasks, list_size* sizeof(char*));
This is not a safe way to realloc, and you are also reallocing the wrong pointer (the first entry in the list, rather than the list itself). If the allocation fails, you have lost the original pointer, and leaked that memory. You should realloc to a temporary variable first, like this:
char *temp = realloc(tasks, list_size* sizeof(char*));
if (temp != NULL)
tasks = temp;
And finally, don't cast the result of malloc().
I was reading about realloc and got confused about a point mentioned there. Consider the code below:
#include <stdio.h>
#include <stdlib.h>
int main () {
int* ptr = NULL;
ptr = realloc(ptr, 10*sizeof(int));
return 0;
}
Is there any danger in allocating memory with realloc using the initially NULL-valued ptr? If instead of:
int* ptr = NULL;
I had this:
int* ptr; // no value given to ptr
would it be a problem to call realloc using ptr?
Is there any danger in allocating memory with realloc using the
initially NULL-valued ptr
None
7.22.3.5
If ptr is a null pointer, the realloc function behaves like the malloc
function for the specified size.
For the second part:
int* ptr; // no value given to ptr
would it be a problem to call realloc using ptr?
If you're using uninitialized pointers then that is a very serious problem indeed since you can't predict what their value will be. The function realloc only works correctly for NULL or values obtained from malloc / realloc.
Otherwise, if ptr does not match a pointer earlier returned by a
memory management function [...] the behavior is undefined
With the specific code shown, there is no problem with using the null pointer initially.
If the variable ptr is uninitialized — not set to 0 or NULL — then any call to realloc() using it is dangerous; the behaviour is undefined and if you are lucky, the program will crash, but if you're unlucky, it will appear to work for a while, until something goes wrong later in the program where it will be hard to spot that the trouble is in code executed a long time ago.
There are those who argue it is better to use malloc() for the initial allocation and realloc() thereafter. There is some justice to the suggestion, not least because you probably wouldn't use ptr = realloc(ptr, 0); to free the memory, even though you could do so (so you don't really need malloc() or free() because realloc() can do all three operations). But the C90 standard requires realloc(0, new_size) to work equivalently to malloc(new_size), and I know of no C library that behaves differently (but there might be some; I've only used a few C libraries, albeit mostly the most widely used ones).
However, in a more general case such as the following code, then there is a subtle problem with the code (but it is not to do with the initial null pointer):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char *ptr = NULL;
size_t len = 0;
char buffer[256];
while (fgets(buffer, sizeof(buffer), stdin))
{
size_t buflen = strlen(buffer) + 1;
if (buflen > len)
{
if ((ptr = realloc(ptr, buflen)) == 0) // Danger!
// ... handle memory allocation failure ...
len = buflen;
}
strcpy(ptr, buffer);
// ... do something with ptr
}
free(ptr);
return 0;
}
What is the danger? The danger is that if the second or a subsequent memory allocation fails and ptr is the only pointer to the allocated memory, you just overwrote its previous value with null. That means you cannot free the allocated memory using ptr any more — you've leaked memory. (For the first allocation, the initial value was 0, the overwritten value was zero, and nothing has changed; there is no memory leak. That's why the loop was added to the code.)
Rule of Thumb
Do not write ptr = realloc(ptr, newsize);
Save the new value into a separate variable until you've tested it.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char *ptr = NULL;
size_t len = 0;
char buffer[256];
while (fgets(buffer, sizeof(buffer), stdin))
{
size_t buflen = strlen(buffer) + 1;
if (buflen > len)
{
char *new_ptr = realloc(ptr, buflen);
if (new_ptr == 0)
// ... handle memory allocation failure ...
ptr = new_ptr;
len = buflen;
}
strcpy(ptr, buffer);
// ... do something with ptr
}
free(ptr);
return 0;
}
This code does not leak memory on an allocation failure.
Auxilliary recommendation: do not use a variable called new; it will make it difficult to compile with a C++ compiler. Even if you have no intention now of converting to C++ (and even though you would probably end up rewriting the memory management if you do), there's no virtue in using the C++ keyword new as a C variable name...unless you explicitly want to prevent compilation with a C++ compiler.
Is there any danger in allocating memory using realloc using the initially NULL-valued ptr?
No, that would exactly be like a malloc.
If instead of:
int* ptr = NULL;
I had this:
int* ptr; // no value given to ptr
would it be a problem to call realloc using ptr?
Yes, there would be a problem. If realloc doesn't get a NULL, it will try to expand memory starting from that location, or may try to free and malloc another part of memory. Since uninitialized variables can have any value, chances are very high, they are not a value realloc likes. If you are lucky, your program would immediately crash.
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.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num = 1;
char* test[8];
sprintf(test[0],"%d",num);
printf("%s\n",test[0]);
}
char *test[8] is an array of 8 char *, or pointers to strings, and since you don't specify, they're all set to garbage values. So sprintf is trying to write data to who-knows-where.
You should use char test[8] instead, which allocates an array of 8 char, and then sprintf(test, "%d", num);.
UPDATE: If you want to use char * pointers, you should allocate space:
char *test = malloc(8 /* see note below */);
sprintf(test, "%d", num);
If you want to use an array of char * pointers, it works the same:
char *test[8]; // 8 pointers to strings
test[0] = malloc(8); // allocate memory for the first pointer
sprintf(test[0], "%d", num);
Keep in mind you would have to call malloc for each of test[0] through test[7] individually.
Also, as mentioned in the comments, if your compiler supports it you should use snprintf(). It's like sprintf but it takes an extra parameter which is the size of the buffer:
snprintf(test, 8, "%d", num);
and guarantees not to use more space than you allow it. It's safer, and if you need to, snprintf returns the amount of space it actually wanted, so if you gave it too little room you can realloc and try again.
Note: some will say this should be malloc(8 * sizeof(char)) (or sizeof *test). They are wrong (in my objectively-correct opinion; note the sarcasm)! sizeof(char) is guaranteed to be 1, so this multiplication is unnecessary.
Some advocate the usage of TYPE *p = malloc(x * sizeof *p) so that if TYPE changes, you'll only need to change it in one place, and sizeof *p will adapt. I am one of these people, but in my opinion you will rarely need to upgrade a char * to another type. Since so many functions use char * and would need to be changed in such an upgrade, I'm not worried about making malloc lines more flexible.
sprintf() does not allocate space for the string; you must do that yourself beforehand.
Look at your warnings:
test.c: In function ‘main’:
test.c:8: warning: ‘test[0]’ is used uninitialized in this function
You allocate an array of 8 pointers, but use one without initializing it. You must call malloc and store the result in test[0] before you can write to the memory pointed to by test[0]. You free it at the end.
A useful function, present in GNU and BSD, is asprintf, which will call malloc for you to allocate enough memory for the formatted string:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int num = 1;
char* test[8];
asprintf(&test[0],"%d",num);
printf("%s\n",test[0]);
free(test[0]);
return 0;
}
(Note that you pass the address of your pointer to asprintf — since your pointer is test[0], its address is &test[0].)
You did allocate space but you you are passing the wrong thing. Try this:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num = 1;
char test[8];
sprintf(test,"%d",num);
printf("%s\n",test);
}
int main()
{
char *str[5];
sprintf(str[0], "%d",55);
printf("%s\n",str[0]);
return 0;
}
This will be work. But, if you specify variable instead of integer constant value show the segmentation fault will be occur. This error will be happened at the time of sprintf function execution. Because user space memory access.