using realloc with a for loop - c

I am using realloc to allocated memory at runtime in dynamic array. Firstly, I allocated a memory with calloc with sizeof a random integer a. In my program, I have taken a=2. After that I want to store some 14 random values generated, so I have to resize the memory using realloc. I am doing the same in a for loop. FOr 1 iteration, realloc works but after that size doesnt increase and a error occurs "corruption in heap". I am not able to understand the problem. Pls help me if you can, in understanding where the problem is occuring and how to solve it.
Thanks a lot.
Below is my code:
j=j*a; //a=3
numbers = (int*) calloc(b, j); //b=14, no of elements I want to store
printf("Address:%p\n",numbers);
if (numbers == NULL)
{
printf("No Memory Allocated\n");
}
else
{
printf("Initial array size: %d elements\n", a);
printf("Adding %d elements\n", b);
}
srand( (unsigned) time( NULL ) );
for(count = 1; count <= b ; count++)
{
if(i <= j)
{
numbers[count] = rand() % 100 + 1;
printf( "Adding Value:%3d Address%p\n", numbers[count],numbers[count] );
i++;
}
if (i > j)
{
printf("Increasing array size from %d bytes to %d bytes\n",j,j*a);
j=j*a;
numbers = (int*) realloc(numbers,j);
printf("Address:%p\n",numbers);
if(numbers == NULL)
{
printf("No Memory allocated\n");
}
}
}
free(numbers);
return 0;
}

The initial array length (length and size are not the same) is b, not a.
Adding b elements? I don't think you are.
Arrays are zero-based in C. You loop should be for(count=0; count<b ; count++).
count is a terrible name for a loop variable. count should hold the number of elements and not be a loop variable.
It's hard to imagine what j could be. Since you use it as the element size in your call to calloc it ought be at least be a multiple of 4, the size of in int. What is it?!
The realloc doesn't seem to bear any relation to the calloc.
I'm sure there are lots of other problems. If you want more help then a clear statement of what your goal is would be required.
EDIT
It sounds like you want something like this:
int capacity = 10;
int count = 40;
int i;
int* array = (int*)malloc(capacity*sizeof(int));
for (i=0; i<count; i++)
{
if (i==capacity)
{
capacity *= 2;
array = (int*)realloc(array, capacity*sizeof(int));
}
array[i] = RandomIntInRange(1, 100);
}
free(array);
Notes:
No error checking. In production code you would check that the allocations succeeded, and the realloc done this way would leak if it failed. But there's no point confusing the message with error checking when you are still at this level of understanding.
No reading input - you can do that.
No writing output - you can do that.

The integer "j" is not initialized in your code, resulting in a = 0 * 3, meaning a will be zero and no memory will be allocated. The segfault is due to you not handling that numbers is NULL. Change to and set j to something meaningful
#include <stdlib.h>
#include <stdio.h>
void
main (int argc, char *argv[])
{
int a = 3;
int j = 1 * a; //a=3
int b = 14;
int *numbers = calloc (b, j); //b=14, no of elements I want to store
int count = 0, i = 0;
printf ("Address:%p\n", numbers);
if (numbers == NULL)
{
printf ("No Memory Allocated\n");
return;
}
else
{
printf ("Initial array size: %d elements\n", a);
printf ("Adding %d elements\n", b);
}
srand ((unsigned) time (NULL));
for (count = 1; count <= b; count++)
{
if (i <= j)
{
numbers[count] = rand () % 100 + 1;
printf ("Adding Value:%3d Address%p\n", numbers[count],
&(numbers[count]));
i++;
}
if (i > j)
{
printf ("Increasing array size from %d bytes to %d bytes\n", j,
j * a);
j = j * a;
numbers = (int *) realloc (numbers, j);
printf ("Address:%p\n", numbers);
if (numbers == NULL)
{
printf ("No Memory allocated\n");
}
}
}
free (numbers);
}

Related

Free list of integers

I was trying to free a list of integers starting from the head and knowing how many elements are in the list, but I am getting an invalid pointer error.
The code is the following:
int* factors = job_factorization(number, size);
printf("Thread %d: job terminated. Result: ", params->thread_id);
int* tmp;
for (int i = 0; i < *size; i++){
printf("%d ", *factors);
tmp = factors;
factors++;
free(tmp);
}
int *job_factorization(int number, int *size) {
int *factors;
int array_size = SIZE_INCREASE;
int factor = 2;
if (number < 2)
return NULL;
factors = (int *) malloc(sizeof(int) * SIZE_INCREASE);
*size = 0;
while (number != 1) {
// check whether the number is divisible by the factor
if (number % factor == 0) {
// if there is no more space available, resize the array
if (*size == array_size) {
array_size += SIZE_INCREASE;
factors = (int *) realloc(factors, sizeof(int) * array_size);
}
// add the factor to the list of prime factors
factors[*size] = factor;
(*size)++;
number = number / factor;
}
else {
// if not a factor, move to the next prime number
factor = next_prime(factor);
}
}
return factors;
}
Does anyone have any idea of the reason why this is happening? I have no clue about it (the function job_factorization works correctly)
job_factorization makes one malloc (and a number of reallocs). To the user of job_factorization this looks like one allocation only and that only needs one free. Like this:
int* factors = job_factorization(number, size);
for (int i = 0; i < *size; i++) {
printf("%d ", factors[i]); // don't increase factors in the loop
}
free(factors); // one free
When you use realloc it replaces the old allocation, so if you first malloc for 1 element, then realloc for 2 elements, the result is one allocation with 2 elements - which requires one free only.

printing 2 characters and keeping them through dynamically allocated 2d array

Hello I am trying to print something like this with 2d array.
Note that when user enters the same number, character should be printed above existing char.
EXPECTED RESULTS:
Input 1: 3 //user1 inputs 3
****
****
**x*
Input 2: 1 //user2 inputs 1
****
****
y*x*
Input 3: 1 //user1 inputs 1
****
x***
y*x*
current results:
enter first: 3
3***
***
**x
enter second: 1
1******
******
xx****
enter first: 2
2*********
*********
***xxx***
But keeping printed values on its previous places.
The problem is that they don't get printed in right order. And also it seems that I haven't done the best job with 2d array which is dynamically allocated.
Here is something what I've tried:
#include <stdio.h>
#include <stdlib.h>
int num(int term)
{
int number1;
int number2;
if(term==1)
{
scanf("%d", &number1);
return number1;
}
if (term==2)
{
scanf("%d", &number2);
return number2;
}
return 0;
}
void function(int a, int b, int result[], int size)
{
int i = 0;
int j = 0;
int desired_num = 0;
int count = 0;
int *arr[a];
for (i = 0; i < a; i++)
arr[i] = (int *)malloc(a * sizeof(int));
for (i = 0; i < a; i++)
for (j = 0; j < b; j++)
arr[i][j] = ++count;
for (i = 0; i < a; i++)
{
for (j = 0; j < b; j++)
{
for (int counter = 0; counter < size; counter++)
{
if (arr[i][j] == arr[a - 1][result[counter] - 1])
{
arr[i][j] = desired_num;
}
if (arr[i][j] == desired_num)
{
printf("%s", "x");
}
else
{
printf("*");
}
}
}
printf("\n");
}
}
int main()
{
int counter = 1;
int i = 0;
int given_number;
int array[20];
for (;;)
{
if (counter % 2 != 0)
{
printf("enter first: ");
given_number = num(1);
printf("%d", given_number);
}
else
{
printf("enter second: ");
given_number = num(2);
printf("%d", given_number);
}
array[i] = given_number;
function(3, 3, array, counter);
counter++;
}
return 0;
}
array[i] = given_number;
i is never changed from the value of 0. You are only ever overwriting the first element of array each iteration. The other 19 elements remain in an indeterminate state.
counter and array are passed to function, as size and result respectively:
This means as size is incremented, it is used as a bounds for accessing elements of result; elements that contain indeterminate values.
for (int counter = 0; counter < size; counter++)
{
if (arr[i][j] == arr[a - 1][result[counter] - 1])
This will surely lead to Undefined Behaviour as those indeterminate values are used to index arr, effectively accessing random memory offsets. This fact alone makes it hard to reason about the output you are seeing, as really anything is valid.
While perfectly valid, the variable-length array of dynamic allocations is a somewhat perplexing choice, especially considering you fail to free the memory allocated by malloc when you are done with it.
int *arr[a];
for (i = 0; i < a; i++)
arr[i] = (int *)malloc(a * sizeof(int));
int arr[a][b]; would work, given a and b are not stack-crushingly large values (or non-positive). You are, or would be, bounded by the size of array in main anyway.
The triply nested loop is confused at best. There is only logic for printing the x and * characters, so you obviously will never see a y.
For each element of arr, you iterate through each element of result. If the current element of arr equals the value of the column selected by the current value of result ([result[counter] - 1]) in the last row (arr[a - 1]) you print x, otherwise *.
Again UB from utilizing indeterminate values of result, but you can see you are printing a * b * size characters, plus newlines, each iteration.
This is severely flawed.
Some other things of note:
The two branches of the if .. else statement in the num function do the exact same thing, just with different identifiers.
The two branches of the if .. else statement in main are identical, other than the first printf in each, and the integer value passed to num, which have the same effect.
This means the only thing that needs to branch is the printf argument.
A generic function for getting an integer would work fine
int get_num(void)
{
int n;
if (1 != scanf("%d", &n)) {
fprintf(stderr, "Could not read input.\n");
exit(EXIT_FAILURE);
}
return n;
}
for use inside main
if (counter % 2 == 0)
printf("enter first: ");
else
printf("enter second: ");
given_number = get_num();
A small issue: printf("%d", given_number); is muddling the output slightly.
There is no reason to repeatedly generate the array. Initialize an array in main to serve as the state of the program. Over time, fill it with the users' selections, and simply print the array each iteration.
Make sure to always check the return value of scanf is the expected number of conversions, and ensure the integers provided by the users will not access invalid memory.
Here is a cursory example.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define EMPTY '*'
#define PLAYER_ONE 'X'
#define PLAYER_TWO 'O'
int get_num(void)
{
int n;
if (1 != scanf("%d", &n)) {
fprintf(stderr, "Could not read input.\n");
exit(EXIT_FAILURE);
}
return n;
}
int main(void)
{
const size_t rows = 6;
const size_t cols = 7;
char board[rows][cols + 1];
memset(board, EMPTY, sizeof board);
/* our rows are now strings */
for (size_t i = 0; i < rows; i++) {
board[i][cols] = '\0';
puts(board[i]);
}
unsigned char turn = 1;
while (1) {
printf("Player %s, Enter column #(1-%zu): ",
turn & 1 ? "One" : "Two", rows);
int input = get_num();
if (1 > input || input > cols) {
printf("Invalid column [%d]. Try again...\n", input);
continue;
}
size_t sel = input - 1;
if (board[0][sel] != EMPTY) {
printf("Column [%d] is full! Try again...\n", input);
continue;
}
size_t n = rows;
while (n--) {
if (board[n][sel] == EMPTY) {
board[n][sel] = turn & 1 ? PLAYER_ONE : PLAYER_TWO;
break;
}
}
for (size_t i = 0; i < rows; i++)
puts(board[i]);
turn ^= 1
}
}

Stuck in a for loop entering values to an array in C language

I am trying to practice with C by making a bubble sort program. The problem until now seems to be that the for loop that is giving values to the cells of the array is stuck after the condition is no longer fulfilled but it doesn't seem to be executing the commands in the loop. I don't know what is happening exactly and I have added some extra lines to see what is happening an these were my conclusions. Here is the code:
#include <stdio.h>
#include <stdlib.h>
void swap(int *x, int *y)
{
int temp = *x;
*x = *y;
*y = temp;
}
int *sort(int *array)
{
int finish = 1;
while (finish = 1)
{
finish = 0;
for (int i = 0; i <= sizeof(array); i++)
{
if ((array + i) > (array + i + 1))
{
swap(array + i, array + i + 1);
finish = 1;
}
}
}
return array;
}
int main()
{
int s, res;
printf("Give me the size of the array being sorted(larger than 1) : ");
do
{
res = scanf("%d", &s);
if (res != 1)
{
printf("Wrong Input!\n");
exit(1);
}
if (s < 2)
printf("Only numbers equal or larger than 2\n");
} while (s < 2);
int array[s];
for (int i = 0; i < s; i += 1)
{
scanf("%d", array + i);
printf("%d %d %d\n\n", *(array + i), i, i < s); // I used this to check if my values were ok
}
printf("end of reading the array"); //I added this line to see if I would exit the for loop. I am not seeing this message
sort(array);
printf("\n");
for (int i = 0; i < sizeof(array); i++)
printf("%d\n\n", array + i);
printf("Array has been sorted! Have a nice day!\n\n************************************************************");
return 0;
}
See the annotations in the code:
#include <stddef.h> // size_t 1)
#include <stdio.h>
#include <stdlib.h>
void swap(int *x, int *y)
{
int temp = *x;
*x = *y;
*y = temp;
}
int *sort(int *array, size_t size) // needs an extra parameter to know the size of the array
{
int finish = 1;
while (finish /* = 1 * you don't want assignment, you want comparison: */ == 1)
{
finish = 0;
for (int i = 0; i /* <= sizeof(array) */ < size - 1; i++) // i should be of type size_t
{
// if ((array + i) > (array + i + 1)) you are not dereferencing:
if(array[i] > array[i + 1])
{
// swap(array + i, array + i + 1); // easier to read imho:
swap(&array[i], &array[i + 1]);
finish = 1;
}
}
}
return array; // why does this function return anything? it is never used.
}
int main()
{
int s; /* , res; no need for an extra variable res */
printf("Give me the size of the array being sorted(larger than 1) : ");
do
{
// res = scanf("%d", &s);
// if (res != 1)
if (scanf("%d", &s) != 1)
{
printf("Wrong Input!\n");
// exit(1); // should be EXIT_FAILURE. Use return instead of exit() when in main().
return EXIT_FAILURE;
}
if (s < 2)
printf("Only numbers equal or larger than 2\n");
} while (s < 2);
int array[s];
for (int i = 0; i < s; /* i += 1* idiomatic: */ ++i) // size_t would be the correct type for s and i.
{
scanf("%d", /* array + i use indexes: */ &array[i]);
printf("%d %d %d\n\n", array[i], i, i < s); // again: indexes. i < s is allready ensured by the condition of the for-loop
}
printf("end of reading the array");
// sort(array); // sort will have no idea about the size of array use
sort(array, s); // instead.
printf("\n");
for (int i = 0; i < /* sizeof(array) 2) */ s; i++)
printf("%d\n\n", /* array + i * again you don't dereference */ array[i]);
printf("Array has been sorted! Have a nice day!\n\n************************************************************");
return 0;
}
1) size_t is the type that is guaranteed to be big enough to hold all sizes of objects in memory and indexes into them. The conversion specifier for scanf() is "%zu".
2) sizeof(array) in main() will yield the number of bytes in array, but you want the number of elements so you'd have to use sizeof(array) / sizeof(*array). But thats not needed since you already know its size. It is s.
This line
printf("end of reading the array");
has no line feed at the end of the string. This is a problem because printf is part of the family of functions called "buffered IO". The C library maintains a buffer of the things you want to print and only sends them to the terminal if the buffer gets full or it encounters \n in the stream of characters. You will not see, end of reading the array on your screen until after you have printed a line feed. You only do this after calling sort(). So all you know is your program is getting into an infinite loop at some point before the end of sort.
So there are actually three loops that could be infinite: the for loop you identified, the while loop in sort and the for loop inside the while loop. As the other answers point out, you have made the classic mistake of using assignment in the while conditional
while (finish = 1)
// ^ not enough equals signs
Unless your C compiler is really old, it is probably outputting a warning on that line. You should heed warnings.
Also, you should learn to use a debugger sooner rather than later. Believe me, it will save you a lot of time finding bugs.
In the sort function sizeof(array) returns the size of the pointer. (you can check it by yourself using printf("%d", sizeof(array).
The solution is to change your function to:
int sort(int* array, size_t size) { ... }
and call it with the correct array size:
sort(array, s);

Allocating memory to 2D array using an array of NULL (c)

thanks for taking the time in reading this.
In my question a "vector" is defined as a 1D dimensional array of integers.
Therefore an array of vectors would be a 2D dimensional array in which every vector can be of a different length.
I'm asked to use:
int** vectors- the 2D array
int size -an integer that represents how many vectors exist inside **vectors
int* sizes-a 1D array of integers that represents the length of the vectors
for example,for:
vectors = {{4,3,4,3},{11,22,33,44,55,66},NULL,{5},{3,33,333,33,3}}.
size is 5 (there are 5 vectors inside vectors).
sizes is {4,6,0,1,5} (4 is the length of the first vector and so on).
size is inputted by the user at the beginning of main() and **vectors&*sizes are dynimacilly allocated with size's value.
I'm asked to write the function:
int init(int ***vectors, int **sizes, int size) which initializes **vectors to be an array of NULLs and *sizes to be an array of zeros.
I came up with this code:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int init(int*** vectors, int** sizes, int size)
{
int i, k,j;
printf("check\n");
*vectors = (int**)malloc(size * sizeof(int*));
if (*vectors == NULL)
return 0;
for (i = 0; i < size; i++)
{
*(vectors + i) = NULL;
}
printf("check 2\n");
for (k = 0; k<size; k++)
{
if (*(vectors+k) != NULL)
printf("didn't work\n");
else
printf("current is null\n");
}
*sizes= (int*)malloc(size * sizeof(int));
if (*sizes == NULL)
return 0;
for (j= 0; j < size; j++)
{
*(sizes + j) = 0;
printf("%d ", *(sizes + j));
}
printf("\n");
return 1;
}
int main()
{
int size, i;
int** vectors = NULL;
int* sizes = NULL;
printf("\nPlease enter an amount of vectors:\n");
scanf("%d", &size);
printf("%d\n", init(&vectors, &sizes, size));
printf("size is %d now\n", size);
// for (i = 0; i < size; i++)
// printf("%d ", *(sizes+i));
printf("check 3\n");
free(sizes);
free(vectors);
printf("check 4\n");
printf("check 5\n");
return 0;
}
forgot to mention that init returns 0 if it fails to allocate memory and 1 otherwise.
printing the "checks" was so I could see where the program fails.
the problem is that no matter what,after printing the last check (check 5)
the program fails.(Run-Time Check Failure #2)
if anyone could help me understand what I'm doing wrong I would HIGHLY appreciate it.
thanks alot for reading and have an amazing day.
edit:
i also printed the array sizes/vectors inside init just to see if it prints zeros/nulls,i don't actually need to do it.
One problem of OP's code is in the pointer arithmetic. Given:
int ***vectors;
*vectors = malloc(size * sizeof(int*));
This loop:
for (i = 0; i < size; i++)
{
*(vectors + i) = NULL;
}
Would iterate over the next unallocated pointer to pointer to pointer to int, while what the OP needs is
for (i = 0; i < size; i++)
{
*(*vectors + i) = NULL; // or (*vectors)[i] = NULL;
}
The same holds in the following loops, where *(sizes + j) is used instead of *(*sizes + j) (or (*sizes)[j]).

efficient way to get numbers from user and fill Matrix

I want to get numbers from user in a single line for example:
2 1 2 3 4
The first number: 2 means that my Matrix should be with size of 2x2 and the next 4 numbers should insert into my Matrix (Matrix dimension should be n²).
Currently I have this:
int dimension, num;
int *mat;
int numcounter = 0;
int i = 0;
int j, k, t;
char temp;
printf("Please enter numbers: ");
do {
scanf("%d%c", &num, &temp);
i++;
if (i == 1)
{
/* Set Matrix dimension. */
dimension = num;
if (dimension < 2)
{
printf("Size must be a valid number");
return 1;
}
else
/* Allocate dimension size. */
mat = (int*)malloc(dimension * dimension * sizeof(int*));
}
else
{
/* Fill Matrix. */
}
} while (temp != '\n' || temp == EOF)
So here I have all the number and now I need to fill my Matrix but instead of put all the numbers inside temp array and then fill my Matrix I wonder how to do that without another memory allocation.
You can do it simply using a VLA. The OP's initial question never mentioned that OP needs to get the input in a line and parse it. I have given that as an answer in the second part. But simply that is not needed. It is not a feasible reason that you have to get the numbers all at once. You can get the size using one scanf and then the elements in another scanf.
scanf("%d", &num);
//Then you know the dimension of the array.
int arr[num][num];
for(size_t i=0;i<num; i++)
for(size_t j =0; j< num; j++)
if( scanf("%d",&arr[i][j]) != 1)
{
fprintf(stderr,"Error in input");
exit(1);
}
Also as you know how many numbers will be read you don't need to continue scanning until you get '\n' or EOF.
Given your case your over complicating things IMHO. As you know the numbers you can get the benefit of VLA.
If you have to get all the numbers in a single line you need to look at 3 functions. fgets() and strtol. Those will help you achieving reading everything in a line and then tokenizing.
To give you a demo of what I said you can do this
#include <stdio.h>
#include <stdlib.h>
#define BUFSIZE 256
int main(void)
{
char line[BUFSIZE];
long temp[BUFSIZE];
int i = 0;
if (fgets(line, sizeof line, stdin) != NULL)
{
const char *ptr = line;
while (*ptr != '\0')
{
char *endptr = NULL;
long val = strtol(ptr, &endptr, 10);
if (endptr != ptr)
temp[i++] = val;
else
break;
ptr = endptr;
}
}
int sz = temp[0];
if( sz <= 0 )
{
fprintf(stderr,"Error in size input");
exit(1);
}
int tempIn = 1;
long arr[sz][sz];
for(size_t i = 0; i < sz; i++)
for(size_t j = 0; j < sz; j++)
arr[i][j]= temp[tempIn++];
for(size_t i = 0; i < sz; i++)
for(size_t j = 0; j < sz; j++)
printf("%ld ",arr[i][j]);
}
In the second code, as you can see fgets has been used which basically read a line and then strtol has been used. As you have mentioned that you will give a single line input of numbers.
Now what we did?
The line scanned and the parsed number by number using strtol. For a brief overview of strtol check this.
Also OP asked for how to use dynamic memory allocation to do the same thing. And there is no way a while loop is needed here. This is redundant. So while modifying I will add the code that will be able to do it much more simpler way.
scanf("%d", &num);
int matIndex = 0;
/* Set Matrix dimension. */
dimension = num;
if (dimension <= 0)
{
printf("Size must be posiitve integer");
return 1;
}
else
{
mat = malloc(dimension * dimension * sizeof *mat);
if ( mat == NULL ){
fprintf(stderr, "%s\n", "Error in malloc");
exit(1);
}
}
// All the numbers will be taken as elements of the dynamically allocated array,
for(size_t i = 0; i < dimension*dimension ; i++)
if( scanf("%d",&mat[i]) == 1){
//ok
}
else{
fprintf(stderr,"Some error occured");
break;
}
When you want to access the i-th row and j-th column element, you can do this mat[i*dimension+j] //equivalent to mat[i][j]
Some useful information:-
Allocating dim*dim memory doesn't let you access the element in the form of mat[i[[j]. Because you allocated a single chunk of memory - you have to calculate the positions explicitly and access the element in the linear array.
You can do all the scanning using scanf() but you need to be careful when having scanf(). But yes you can get this thing done using scanf also.
Also there is another thing to know about. The VLA will have automatic storage duration and limiting the memory you can have use this way. The dynamically allocated memory has much higher limit giving you a scope of having much larger dimensions array.
Note that in dynamic memory allocation you will need to free the allocated memory when you are done working with it.
If you want to use mat[i][j] not mat[i*dim+j] you can consider creating one jagged array.
Few things that you will need:
Reading Suggestion:
How to debug small programs
Beginner's guide away from scanf
Book list
You can use following code:
Note: You can redirect STDIN to your file. See posts available here
#include <stdio.h>
#include <stdlib.h>
int main()
{
int D, i, j;
freopen("testfile.txt","r",stdin);
printf("Ender dimention of matrix: ");
scanf("%d",&D);
int** matrix = malloc(D*D*sizeof(int));
for(i=0; i<D; i++)
{
for(j=0; j<D; j++)
{
printf("Ender element of matrix: ");
scanf("%d",&matrix[i][j]);
}
}
printf("Matrix is: \n");
for(i=0; i<D; i++)
{
for(j=0; j<D; j++)
{
printf("%d ", matrix[i][j]);
}
printf("\n");
}
free(matrix);
return 0;
}

Resources