Free dynamically allocated memory in C - c

because I am new in C, I am not sure how to ask it, but here is my Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ARRAY_SIZE 500
int main(int argc, char *argv[]) {
for (int j=0; j<ARRAY_SIZE; ++j) {
printf("Memory Size: %d\n", j);
int bytes = (1024*1024);
char *data;
data = (char *) malloc(bytes);
for(int i=0;i<bytes;i++){
data[i] = (char) rand();
}
}
//Free all Char*data that I have declared inside the for loop here
return 0;
}
So I need to free my data variables that I have allocated inside the for loop. How is it possible? I am testing some portion of my memory blocks. So I am running it because I wanna see how far it goes. So the above code gets me to that point. Now I am trying to run a loop below threshold point so that I can assure, the memory that I am working with is good and can sustain. To do so, I need to clear the memory that I have created inside the loop.
Thanks in advance

I think you'll want an array of pointers and then free those pointers after the loop.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ARRAY_SIZE 500
int main(int argc, char *argv[]) {
char * data[ARRAY_SIZE] = {0};
for (int j=0; j<ARRAY_SIZE; ++j) {
printf("Memory Size: %d\n", j);
int bytes = (1024*1024);
data[j] = (char *) malloc(bytes);
for(int i=0;i<bytes;i++){
data[j][i] = (char) rand();
}
}
for (int j=0; j<ARRAY_SIZE; ++j) {
free(data[j]);
}
return 0;
}

Since you assigned the return value of malloc to data which is defined inside of the loop, that memory is lost at the end of each iteration of the loop.
You need to add a call to free at the bottom of the loop.
for (int j=0; j<ARRAY_SIZE; ++j) {
printf("Memory Size: %d\n", j);
int bytes = (1024*1024);
char *data;
data = (char *) malloc(bytes);
for(int i=0;i<bytes;i++){
data[i] = (char) rand();
}
free(data);
}

Related

Is there a way to initialize all int array elements to zero except for loop

Is there a way to initialize all int array elements to zero except a for loop where we loop through to set values to zero. Here the size of array is decided by input of user.
#include <stdio.h>
int main() {
int num_cases = 0;
scanf("%d", & num_cases);
int arr_counter[num_cases];
for (int x = 0; x < num_cases; x++) {
arr_counter[x] = 0;
}
}
Yes, you can do that in multiple ways under C standard. For example:
memset() [Stack and Heap]
calloc() [Heap Only]
loops, e.g., do-while, while and for [Stack and Heap]
{ } [Stack Only]
1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int arr[10];
size_t len_arr = sizeof(arr) / sizeof(*arr);
memset(arr, 0, sizeof(arr));
for(size_t i = 0; i < len_arr; i++)
printf("%d\n", arr[i]);
return EXIT_SUCCESS;
}
Note: We can use memset() to set all values as 0 or -1 for integral data types also. It will not work if we use it to set as other values. The reason is simple, memset() works byte by byte.
2
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int *arr = calloc(10, sizeof(int));
if(!arr)
{
fprintf(stderr, "bad ptr");
return EXIT_FAILURE;
}
for(size_t i = 0; i < 10; i++)
printf("%d\n", arr[i]);
free(arr);
return EXIT_SUCCESS;
}
Note: You need to keep track of arr maximum length.
Note: malloc() leaves garbage value in your pointer, whereas calloc() uses memset() to initialize them to 0.
Note: You need to free the heap allocated resource.
3
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int arr[10];
size_t len_arr = sizeof(arr) / sizeof(*arr);
for(size_t i = 0; i < len_arr; i++)
arr[i] = 0;
for(size_t i = 0; i < len_arr; i++)
printf("%d\n", arr[i]);
return EXIT_SUCCESS;
}
Note: You can use any of your favorite loop.
4
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int arr[10] = {};
size_t len_arr = sizeof(arr) / sizeof(*arr);
for(size_t i = 0; i < len_arr; i++)
printf("%d\n", arr[i]);
return EXIT_SUCCESS;
}
Use calloc function available in stdlib.h
#include<stdio.h>
#include<stdlib.h>
int main(){
int num_cases;
scanf("%d", &num_cases);
int* arr = (int*)calloc(num_cases,sizeof(int));
return 0;
}
To initialize each element of Array you have two approaches:
If you are going for static memory allocation, you can initialize it like this:
int arr[10] = {};
If you are going for dynamic memory allocation, you can use calloc function.
int *arr = (int) calloc(numberOfElementsInArray,sizeOfEachElement);
In your case, it would be like:
int *arr_counter = (int*) calloc(num_cases,sizeof(int));
NOTE: You need to include malloc.h header file to use calloc function.

Solving segmentation fault

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void main() {
int i,j;
int *u = malloc(10000 * 10000 * sizeof(int));
for (i=0; i<10000; i++)
{
for(j=0;j<10000;j++)
{
u[i][j]=i+j;
}
}
free(u);
}
I edited my program. when compiling this program, I get an error "subscripted value is neither array nor pointer nor vector".
how can i allocate memory?
You have allocated memory for a single dimensional array and you are trying to use it as a two-dimensional array. There is a slight alteration which you need to do to your code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
int i,j;
int *u = malloc(10 * 10 * sizeof(int));
for (i=0; i<10; i++)
{
for(j=0;j<10;j++)
{
u[10*i +j]=i+j; // this is how you can use it
}
}
for (i=0; i<10; i++)
{
for(j=0;j<10;j++)
{
printf("%d ",u[10 *i +j]);
}
printf("\n");
}
free(u);
return 0;
}
Note that I have used size 10*10, you can do the same for whatever size you need.
Check-here
You can't allocate large arrays on heap directly in the declaration.
You can allocate large arrays using malloc as follows
#include <stdlib.h>
int *matrix = malloc(ROW * COLUMNs * sizeof(int));
Always use column major order to search for elements.
Explanation for column major order can be found here Accessing elements in a matrix
Here size = 10000
Always after you complete your task,free the memory
free(matrix);

C: Printing out the value and memory location of each element of an array using pointers?

I have generated a random array inside the main function, How can I properly print it out using a separate function and inside the function print out the value and memory location of each element of that array using pointers. Here is my code so far:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void printArray(int *pointertoArray, int *Size);
int main (void)
{
srand(time(NULL));
int array[10];
int *pointer = NULL;
for(int i = 0; i < size; i++)
{
array[i] = rand();
*pointer = array[i];
printArray(*pointer,size);
}
}
void printArray(int *pointerToArray, int *size)
{
int i = 0;
do
{
printf("\nValue %d = %p ",i,*pointerToArray);
i++;
}
while(i < size);
}
Here is what I am trying to achieve:
value 1 = 0x7fff0815c0e0
.....
value 10 = 0x7fff0815c0ec
int *size should be int size. You don't pass a pointer, and you don't need a pointer.
Actually, size_t size would be more appropriate.
The call to printArray should be located after the loop. You only want to print the array once.
printArray(*pointer, size); should be printArray(array, size);.
pointerToArray should be named array or pointerToInts.
The value of the element is pointerToArray[i], not i.
The address of the element is pointerToArray+i, not *pointerToArray.
The loop in printArray should be top-tested. (No reason for it to be bottom tested, so play it safe.)
main is declared to return an int, but doesn't.
We get,
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void printArray(int *array, size_t size);
int main() {
srand(time(NULL));
int array[10];
for (int i = 0; i < size; ++i) {
array[i] = rand() % 1000;
}
printArray(array, sizeof(array)/sizeof(array[0]));
return 0;
}
void printArray(int *array, size_t size) {
for (int i = 0; i < size; ++i) {
printf("Value # %p = %d\n", array+i, array[i]);
}
}
Alternative:
void printArray(int *pointerToInt, size_t size) {
for (; size--; ++pointerToInt) {
printf("Value # %p = %d\n", pointerToInt, *pointerToInt);
}
}

Null pointer using const instead of variable declaration

I have a problem I can't figure out. I wrote this code to shuffle the elements of an array:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
const char *array[]={"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
int main(int argc, char **argv)
{
int i, tmp, randomize, size;
size = sizeof(array)/sizeof(*array);
srand(time(NULL));
for(i=size;i>0;i--){
randomize=0+(rand()%size);
tmp=(int)array[i];
array[i]=array[randomize];
array[randomize]=(char*)tmp;
}
for(i=0;i<size;i++)
printf("%s", array[i]);
return 0;
}
When I run the program, this is the iutput:
azlngiwexbv(null)uscphqjyrodmtk
I can't understand why the pointer is sometimes null and I can't understand why, changing the source code in this way:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char **argv)
{
char *array[]={"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
int i, tmp, randomize, size;
size = sizeof(array)/sizeof(*array);
srand(time(NULL));
for(i=size;i>0;i--){
randomize=0+(rand()%size);
tmp=(int)array[i];
array[i]=array[randomize];
array[randomize]=(char*)tmp;
}
for(i=0;i<size;i++)
printf("%s", array[i]);
return 0;
}
Everything works fine.
Thanks.
Start loop from size-1, you are pointing out of array in array[size] (first loop iteration).
for (i=size-1; i>=0; i--)
You should avoid casting whenever possible, and it is rarely necessary to do so.
Unless you plan on using argc and argv[], use the simpler form for main(): int main(void). This will remove some compiler warnings, and you should have these enabled; remove all warnings emitted by your compiler.
You cast a pointer to char to int to store it in tmp, and then you cast tmp back to (char *). Just declare tmp as a pointer to char to start with. The first loop counts down from size to 0; this is out of array bounds to start, but why not just use the conventional loop construction: for (i = 0; i < size; i++)? Also, you should consider using size_t for array indices; it is an unsigned integer type guaranteed to be able to hold any array index, and is also the type returned by the sizeof operator.
Further, in your first version you have declared array as an array of pointers to const chars. You can do this, but you need the temporary storage variable tmp to agree with the const type qualifier.
Here is your code with the above changes. There are no casts, it compiles without warnings, and it works.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
const char *array[] = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
const char *tmp;
size_t i, size;
int randomize;
size = sizeof(array) / sizeof(*array);
srand(time(NULL));
for(i = 0; i < size; i++){
randomize = (rand() % size);
tmp = array[i];
array[i] = array[randomize];
array[randomize] = tmp;
}
for(i = 0; i < size; i++)
printf("%s", array[i]);
putchar('\n');
return 0;
}

How should I implement a rollDice() function in C?

I try to implement a function meant to roll a dice a certain amount of time.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int * rollDice(int len) //len = times the dice is rolled.
{
int ints[len];
int i = len-1;
while(i>0)
{
ints[i--] = (rand()%6)+1;
}
return ints;
}
int main(int argc, const char * argv[])
{
int * ints = rollDice(10);
for(int i =0; i<10; i+=1)
{
printf("%d ",*(ints+i));
}
return 0;
}
Program always prints this, is my conception of pointers false ?
104 0 0 0 1919706998 2036950640 1667723631 1836545636 16 48
You cannot do this
return ints;
It's declared on the stack. You need to either pass it in with enough memory or allocated the memory in the function using malloc and pass it back.
int * rollDice(int len) //len = times the dice is rolled.
{
int *ints = malloc(sizeof(int) * len);
int i = len-1;
while(i>0)
{
ints[i--] = (rand()%6)+1;
}
return ints;
}
Harry's answer is right; you can't return the address of a local variable. That variable is destroyed as soon as the function returns.
Instead of having to allocate memory in the function, just pass the array to be filled into the function:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NUM_DICE 10
void rollDice(int *dice, int num_dice)
{
int i;
for (i = 0; i < num_dice; i++) {
dice[i] = (rand() % 6) + 1;
}
}
int main(int argc, const char * argv[])
{
int dice[NUM_DICE];
srand(time()); /* Don't forget this! */
rollDice(&dice, NUM_DICE);
for(int i = 0; i < NUM_DICE; i++)
{
printf("%d ", dice[i]); /* Easier to use brackets than pointer arithmetic. */
}
return 0;
}

Resources