For this code
#include <stdlib.h>
#include <stdio.h>
int *f (int n)
{
int *ptr = malloc (sizeof (int));
*ptr = n;
return ptr;
}
int main()
{
int i;
int **ptr = malloc (sizeof (int *));
ptr[0] = f (0);
for (i = 0; i < 5; ++i)
{
ptr = realloc (sizeof (int *) * (i + 2));
ptr[i + 1] = malloc (sizeof (int));
ptr[i + 1] = f (i + 1);
}
for (i = 0; i < 5; ++i)
{
printf ("%d\n", *ptr[i]);
free (ptr[i]);
}
free (ptr);
return 0;
}
does program allocate twice than it is needed?
Yes, You don't need the malloc in main as it is immediately overwritten on the next line and you leak that memory. Is this a homework question?
EDIT for question change
This is now leaking memory in an odd way.
The first few lines aren't leaking but when you get into the loop you're allocating and assigning randomly. (As a first, realloc takes as it's first arguement a pointer to reallocate, so you're missing ptr in there)
Now you're allocating ptr to be of size 2, then 3 then 4 etc... up to 6. And then immediately leaking that memory as you overwrite the pointer with the call to f()
You could write that all like this:
int i;
int **ptr = malloc (sizeof(int*) * 6);
for (i = 0; i < 6; ++i)
{
ptr[i] = f(i);
}
for (i = 0; i < 6; ++i)
{
printf ("%d\n", *ptr[i]);
free (ptr[i]);
}
free (ptr);
return 0;
As an aside, you should in general try not to allocate memory too often, it is relatively slow. If you can use the stack you should, and if not, try and allocate all the memory you need up front, calling realloc in a loop is a bad idea and should be avoided.
In this specific case you don't need a pointer to a pointer, you could have just allocated one array of 6 integers, with int* array = malloc(sizeof(int) * 6) and then array[0] = 0; which would be easier and better.
Yes, it does allocate twice the needed memory. Also, the value of "ptr" in main is overwrite by return of "f" so you don't even have a chance to free it. You could remove the call to malloc in "main":
int main()
{
int *ptr = f (3);
printf ("%d\n", *ptr);
free (ptr);
return 0;
}
Related
so I am learning and trying to figure out memory allocation in c, in this piece of code, is the memory allocated correctly or no? Do I need to allocate the array too or is the array already allocated because everything that user inputs goes to the array(will be stored in the array)?
#include <stdio.h>
#include <stdlib.h>
int main() {
int i;
int arr[20];
int b;
int *ptr;
ptr = &b;
ptr = (int*) malloc(20 *sizeof(int));
//find largest element in array
printf("Enter the number of elements: ");
scanf("%d", &b);
if(ptr == NULL)
{
printf(" No memory allocated.");
exit(0);
}
for (i = 0; i < b; ++i) {
printf("Enter number%d: ", i + 1);
scanf("%d", &arr[i]);
}
for (i = 1; i < b; ++i) {
if (arr[0] < arr[i])
arr[0] = arr[i];
}
free(ptr);
printf("Largest element = %d", arr[0]);
return 0;
}
You can clean up the malloc call:
ptr = malloc( 20 * sizeof *ptr );
You don’t need to cast the result of malloc unless you using an ancient pre-C89 implementation or C++ (in which case you should use new/delete instead of malloc/free, or more preferably a container type like vector).
sizeof *ptr is equivalent to sizeof (int) in this case.
However, you aren’t actually using that memory - you allocate it and free it, but you never write anything to it.
You initially assign &b to ptr, but then you overwrite it with the result of the malloc call, so if you’re expecting that memory to be attached to b somehow, be aware that it isn’t.
Consider the code below:
#include < stdio.h >
#include < stdlib.h >
#define SIZE 10
int main() {
int * p, i;
p = malloc(SIZE * sizeof(int));
if (p == NULL) {
printf("malloc failed.\n");
return 1;
}
for (i = 0; i < SIZE; i++)
* (p + i) = i * i;
for (i = 0; i < SIZE; i++)
printf("%d\n", * p++);
free(p);
return 0;
}
This code doesn't work. However I am not sure why. My professor gave an explanation that doesn't make much sense to me. Supposedly the free function doesn't work.
From what I understand, you can only free pointers that were created using malloc. And here we modify that pointer before sending it to free, thereby making our statement invalid.
Is this the correct way to critique that code?
And here we modify that pointer before sending it to free, thereby making our statement invalid.
Is this the correct way to critique that code?
Yes, code is not freeing the original pointer allocated due to p++ which increments the pointer with each loop iteration.
Instead, print in such a way p is not changed.
for (i = 0; i < SIZE; i++) {
// printf("%d\n", * p++);
printf("%d\n", p[i]);
// or
printf("%d\n", * (p + i));
}
// With above change, `p` is the same as the original allocated value.
free(p);
I want to call a function that uses my 2d dynamic array to create another 2d dynamic array and then rewrite the value for my first array. So the code is something like this:
#include <stdio.h>
#include <stdlib.h>
int **bigger(int **A)
{
int i;
int **A2 = (int **)malloc(10 * sizeof(int *));
for(i = 0; i < 10; i++)
A2[i] = (int *)malloc(10 * sizeof(int));
return A2;
}
int main(void)
{
int i;
int **A = (int **)malloc(5 * sizeof(int *));
for(i = 0; i < 5; i++)
A[i] = (int *)malloc(5 * sizeof(int));
A = bigger(A);
for(i = 0; i < 10; i++)
free(A[i]);
free(A);
return 0;
}
If I check it with valgrind --leak-check=yes I get total heap usage: 6 allocs, 3 frees, 240 bytes allocated. How can I solve this memory leak ?
TL:DR, you're not re-writing, you're overwriting.
The problem is in
A = bigger(A);
inside bigger() function, you're allocating new memories and then, storing the same back into A, which makes you lose the pointer to previously allocated memories, thus rendering them unreachable and are not free()-d. Those causes the leak here.
You need to use realloc() for resizing already malloc()ed memory regions.
Otherwise, before you call malloc() again, inside the bigger(), you ought to free() the available memories.
The question is how to correctly allocate/free the memory in this example:
void test(char*** array, int* count) {
*array = malloc(sizeof(char*) * MAX_ARRAY);
while (...) {
(*array)[i] = (char*)malloc(strlen(fooString));
}
}
call of the function:
char** array;
int count;
test(&array, &count);
// now free the memory - i think i have to?
for(i = 0; i < count; i++) {
free(array[i]); // <-- crash here
}
free(array);
It looks like that array[0] has a different address inside the test-function than outside. How can this be? Looks like i misunderstood sth, because the address of array is the same outside and inside the function.
Edit: The Problem is that i am not able to free the allocated memory (see "crash here" in code). Why? And how will it work?
Instead of
void test(char*** array, int* count) {
*array = malloc(sizeof(char*) * MAX_ARRAY);
while (...) {
(*array)[i] = (char*)malloc(strlen(fooString));
}
}
do
void test(char*** array, int count) {
*array = malloc(sizeof(char*) * count); // number of pointers
for (int i = 0; i < count; ++i)
{
(*array)[i] = malloc(strlen(fooString));
}
}
although i am not sure about what fooString is since you don't show the decl/def. Normally you would allocate one byte extra for the \0
(*array)[i] = malloc(strlen(fooString) + 1)
this seems to work
#include <stdio.h>
#include <inttypes.h>
#include <malloc.h>
#include <string.h>
char fooString[256];
void test(char*** array, int count)
{
int i = 0;
*array = malloc(sizeof(char*) * count);
for (i = 0; i < count; ++i)
{
(*array)[i] = malloc(strlen(fooString)+1);
}
}
int main()
{
char** array = NULL;
int count = 100;
int i = 0;
test(&array, count);
for(i = 0; i < count;++i)
{
free(array[i]);
}
free(array);
return 0;
}
For your particular problem:
You allocate (*array)[i] which is a char* to strlen(fooString) which is usually equivalent to sizeof(char) * strlen(fooString) : this is error prone. You should use sizeof(*((*array)[i])) in this case to be sure not to miss the correct type.
To free it, loop from i = 0 to i < MAX_ARRAY and call free(array[i])
What you put in place of ... in your code is very important.
In general, when allocating memory, be sure to respect these general ideas:
If a functions allocates memory it frees it itself except when it is needed outside afterwards.
If a function allocates memory needed outside afterwards, it does just this.
This allows for better code architecture and easier freeing of the memory.
For example:
First point:
void foo()
{
char *a;
a = malloc(sizeof(*a) * 5);
a[0] = 'a';
a[1] = 'b';
a[2] = 'c';
a[3] = 'd';
a[4] = 0; //or '\0' if you prefer
do_something_cool(a);
free(a);
}
The function foo allocates memory, processes it, and frees it.
Second point:
char *halfstrdup(char *str)
{
int len;
int i;
char *newstr;
len = strlen(str);
newstr = malloc(sizeof(*newstr) * len / 2)
for (i = 0; i < len; i++)
{
if ((i % 2) == 0)
newstr[i / 2] = str[i];
}
return (newstr);
}
void foo2()
{
char *half;
half = halfstrdup("Hello, world !");
do_something_cooler(half);
free(half);
}
The function halfstrdup just allocates and sets the memory you need and returns it, the function foo2 allocates memory through the use of halfstrdup, then uses it and frees it.
Do not forget to free before losing track of your pointers, for example after returning from foo or foo2, you won't be able to free the allocated memory.
Im having some trouble understanding how the pass by value mechanism works in c with pointers. Here is my contrived example...
In my main function, I malloc a pointer to an array of int:
int ** checkMe;
checkMe = malloc(sizeof(int *) * 10);
I understand that this operation sets a side a block of 10 chunks of memory, each block big enough to hold the pointer to an int pointer. I receive back the pointer at the start of this block of 10 chunks.
I have another function that takes that double pointer as an argument:
void test2dArray(int ** arr, int size) {
int i, j;
for (i = 0; i < size; i++) {
// arr[i] = malloc(sizeof(int) * size);
for (j = 0; j < size; j++) {
arr[i][j] = i * j;
}
}
}
Whenever I leave the commented section as is, and try to malloc the space for the int in main like this:
int ** checkMe;
checkMe = malloc(sizeof(int *) * 10);
for (i = 0; i < 10; i++) {
checkMe[i] = malloc(sizeof(int));
}
test2dArray(checkMe, 10);
I get memory clobbering whenever I iterate checkMe after the test2dArray call in main.
But if I malloc the space for the int in test2dArray instead (by uncommenting the commented line above) and change my call from main to this:
int ** checkMe;
checkMe = malloc(sizeof(int *) * 10);
test2dArray(checkMe, 10);
the memory clobbering goes away and I can reference checkMe just fine after the function call.
I understand that checkMe is being passed into test2dArray by value. I think this means that the address that is returned by checkMe = malloc(sizeof(int *) * 10); is copied into the function.
I don't understand why the int *'s that checkMe stores gets lost if I don't malloc the space from within test2dArray
When you are allocating in main you are not allocating for 10 integers,
checkMe[i] = malloc(sizeof(int));
change it to
checkMe[i] = malloc(sizeof(int) * 10);
for (i = 0; i < 10; i++) {
checkMe[i] = malloc(sizeof(int));
}
You are only allocating memory for 1 int in each loop iteration. So you have an array of 10 pointers, each pointing to sizeof(int) bytes of memory.
test2dArray(checkMe, 10);
only works for arrays of 10 pointers pointing to at least 10*sizeof(int) memory. You should change the line above to checkMe[i] = malloc(sizeof(int)*10);
Your bug is the difference between this:
checkMe[i] = malloc(sizeof(int));
and this:
arr[i] = malloc(sizeof(int) * size); // size = 10