dynamic array with unknown size - c

I want to write a program in C where the user types in 2 numbers a and b.
0 < a < INT_MAX
a < b < INT_MAX
The program checks how many Prime numbers are in between a and b and saves all of them in a dynamic array.
For the malloc function I need the size of the array, which means I have to first check all numbers if they are prim numbers just to get the size of the array,
then use malloc(),
and then check all numbers again to fill the array.
Is there any possibility to make this run faster and not doing the same thing twice?
for (int i = a; i <= b; i++)
{
if (check_if_prime(i) == 0)
size++;
}
primze_numbers = malloc(size*sizeof(int));
int j = 0;
for (int i = a; i <= b; i++)
{
if(check_if_prime(i) == 0)
{
prime_numbers[j] = i;
j++;
}
}

Since the size is unknown in the beginning, allocating the space for the size of one more element is inefficient.
One possible solution is: reallocate the space(Use realloc) twice the size of the previous size whenever the size is not enough.
Real size - Space size
0 0
1 1
2 2
3 4
4 4
5 8
6 8
7 8
8 8
9 16
10 16
... ...
This way, the times of reallocation is not much, and you don't waste much space.

If you are able to use c++ - you can use std::vector which solves your problem.

Related

how to find the number of elements present in an array in C

suppose I have an array a[10] and it is filled up to 6 places example a[]={10,20,30,40,50,60} now rest 4 places are empty, now how do I print the number of places that are filled in an array-like in the above case it should print 6, given the scenario that I do not know the array beforehand like I do not have any clue what size it is or the elements that are there inside.
int a[]={10,20,30,40,50,60} initilizes all 6 elements.
int b[10]={10,20,30,40,50,60} initilizes all 10 elements, the last ones to 0.
There is no partial initialization in C.
There is no specified "empty".
to find the number of elements present in an array in C
size_t elemnt_count_a = sizeof a / sizeof a[0]; // 6
size_t elemnt_count_b = sizeof b / sizeof b[0]; // 10
I do not know the array beforehand
In C, when an array is defined, its size is known.
if the array is a[]={10,20,30,40,50,60}
here is my psedocode -
int size = 0;
if(i = 0; i < a.length(); i++) {
if(a[i] != null)
size++
}
the value of size should print 6

Store rows of numbers from a list into arrays without leaving empty cells

I want to read rows of numbers from a file and store each of the rows into separate array to then sort and find the median of each array. The problem I'm having is that each row can have a different amount of numbers in it. I though about using a 2D array that would have enough space to fit the largest row in my file. The problem I see with this is that shorter rows in my file would have empty cells in the array and that could cause errors in the sorting and median.
Is there anyway to store each row of the list without having empty cells in the 2D array?
Here's an example of the number list
1 2 3 4 5
5 2 8 5 7 4 3
3 2 5 4 6 5
2 3 1 6 5
9 6 4 6 5 0
Yes you certainly can.
Use dynamic memory allocation for that. This is where it can be useful.
int *p[5];
p[0]= malloc( sizeof(int)*10);
if( p[0]== NULL)
{
fprintf(stderr,"Error in malloc");
exit(1);
}
p[1]= malloc( sizeof(int)*5);
if( p[1]== NULL)
{
fprintf(stderr,"Error in malloc");
exit(1);
}
..
free(p[0]);
free(p[1]);
This way now you have created an array of different sizes. Now to remmeber the sizes you can mention another array sizeArr which will hold the sizes of different arrays.
What I mean is sizeArr[0]=10 and sizeArr[1]=5 denoting the number of elements in p[0] and p[1].
Inputting and outputting the elements of p[0] and p[1] will be similar to that of an array.
if (scanf("%d", &p[0][0]) == 1)
// work with p[0][0];
else
...EOF or conversion failure...
Looping and printing would be similar to
for(size_t arrIndex = 0; arrIndex < 5; arrIndex++)
for(size_t i = 0; i< sizeArr[arrIndex]; i++ )
printf("%d", p[arrIndex][i]);
Here the benefit will be you will not have to worry about unused memory locations. You will allocate whatever memory you need. Also you can change then as you need using realloc() etc.
Note: In this case don't forget to free the memory dynamically allocated after you are done working with it.

Fast / efficient identification of two 2D arrays for sameness in C

I'm working on a search algorithm project, finding the solution for the 16 puzzle.
I have two lists of structs that contain a 2D array board[N][N]
The numbers in the list are unique in a range of 0-15, the difference is their order.
BoardA = 0 1 2 3 BoardB = 4 1 2 3
4 5 6 7 0 5 6 7
8 9 10 11 8 9 10 11
12 13 14 15 12 13 14 15
As you can see, the only difference between boards will be the order of the numbers.
Obviously it is possible to iterate through each board checking if
BoardA[i][j] == BoardB[i][j]
However, if there are hundreds or thousands of boards on a list, comparing them this way is undesirable.
Is there a way to quickly or efficiently compare two boards for sameness?
The elements of a two-dimensional array are located in a contiguous memory block. So to compare two arrays, you are just comparing two memory blocks. The fastest way to do it is with memcmp(). You did not specify what type each array element is, so I will use int and you can replace it with another type if your elements are not ints.
if (memcmp(BoardA, BoardB, sizeof(int) * N * N) == 0) {
/* equal */
} else {
not /* equal */
}
You might save a few cycles with tricks like memcmp(), but really the simple, straightforward comparisons will optimize well. If you exit early on failure, then it will only compare all elements in the case where the arrays are equal, in which case every comparison is needed anyway, even with memcmp().
So keep it simple:
int equals(int (*a)[4], int (*b)[4]) {
for (int i = 0; i < 4; i += 1) {
for (int j = 0; i < 4; j += 1) {
if (a[i][j] != b[i][j]) return 0;
}
}
return 1;
}

Copying matrix from .txt into array

I have a task to read matrix from .txt file and then make an 2D array in C. I read numbers well but I have a problem with writing these numbers into array because I need to allocate memory because im not sure how big the matrix will be.
int read()
{
FILE *f;
int number, i, j, size;
f = fopen("matrix.txt","r");
if (f == NULL)
{
printf("Error reading matrix.txt\n");
return 1;
}
printf("Sucess! \n");
fscanf(f, "%d",&size);
printf("Size of matrix: %d\n", size,size);
int* matrix;
matrix = malloc(size * sizeof(int));
for(; feof(f) == 0;)
{
for(i = 0; i < size; i++)
{
for(j = 0; j < size; j++)
{
fscanf(f,"%i",&number);
// *(*(matrix+j)+i) = number;
printf("%i\t",number);
}
printf("\n");
}
}
fclose(f);
To my understanding, matrix is of type int* and you intend to store size*size elements read from the file into it. First of all, you should allocate memory for size*size times the size of int, which can be done as follows.
matrix = malloc(size * size * sizeof(int));
Next, as you iterate via i and j over the matrix entries which are read from the file, you need to do a proper address calculation. As matrix is of type int*, this can be done as follows.
matrix[ i * ( size - 1 ) + j ] = number;
That being said, perhaps it would be better to have matrix of type int** and allocate space for the rows manually. By doing so, you could do the access to the elements by
matrix[ i ][ j ] = number;
which is perhaps more intuitive.
You can do :
matrix[(size-1)*i+j]=number
To fill the array, that is the usual way to simulate 2D arrays in C, to understand from where did (size-1)*i+j come from notice this example :
1 2 3
4 5 6
7 8 9
the result array is : 1 2 3 4 5 6 7 8 9.
So when we begin in the first row and first column, in the result array 1 is the first element so its index is zero.
When we advance one row(from 1 to 4) we advance three positions in the result array so the index is 3.
Now if we begin with column 1(second column) and the first row we have 2 which has index 1 in the result array, if we advance one row(from 2 to 5) we also advance 3 positions and the index is 4.
Notice that 3 is actually the size of matrix and I think you can verify that i*(size-1)+j is working, the size-1 is like this because C arrays are zero-based.
Note
If your file only has one matrix, I recommend you to get rid of the outermost loop , a simple mistake(like a new line after the matrix or space) will cause a call to fscanf(f,"%i",&number) without finding a number(I'm not sure what will happen then).
Also you should allocate size*size of ints.

c beginner, vectors

I'm a c beginner and i've a problem (as usual). I wrote this simple program:
#include <stdio.h>
#define SIZE 10
main()
{
int vettore[9];
int contatore1,contatore2;
for(contatore1 = 0; contatore1 <= 9; ++contatore1)
{
vettore[contatore1] = contatore1*2;
}
printf("%d\n\n", vettore[9]);
for(contatore2 = 0; contatore2 < 10; ++contatore2)
{
printf("%d\n", vettore[contatore2]);
}
printf("\n%d\n", vettore[9]);
return 0;
}
The output of this program is:
18
0
2
4
6
8
10
12
14
16
9
10
Why the value of vettore[9] changes 3 times? And why it has the correct value only on the first line of the output? thank you :)
C arrays are zero based so valid indexes for a 9 element array are [0..8]. You are writing beyond the end of your array. This has undefined results but is likely corrupting the next stack variable.
In more detail... vettore has 9 elements, which can be accessed using vettore[0] ... vettore[8]. The final iteration of your first loop writes to vettore[9]. This accesses memory beyond the end of your array. This results in undefined behaviour (i.e. the C standard does not specify expected outcome here) but it is likely that the address of vettore[9] is the same as the address of contatore2, meaning that the latter variable is written to.
You have a similar problem in the next loop which prints more elements than vettore contains.
You can fix this by changing your loops to
for(contatore1 = 0; contatore1 < 9; ++contatore1)
for(contatore2 = 0; contatore2 < 9; ++contatore2)
Note that it would be safer if you changed to calculating the size of the array instead, by using sizeof(vettore)/sizeof(vettore[0]) in the exit test of your loops in place of hard-coding 9.
Your array vettore has 9 elements, but by referencing vettore[9], you're actually referencing the 10th element (since element indexing starts from 0). So it's some random location on the stack, without a well-defined value.
The solution is to index only up to vettore[8], or define vettore to have size 10.
check this out:
for(contatore2 = 0; contatore2 < 10; ++contatore2)
{
printf("%d\n", vettore[contatore2]);
}
you are displaying 11 elements of the vettore array (which is defined as a 9 ints array). I think that the error is in the random allocation on the stack
the vettore size as you defined is 9
int vettore[9];
and in your loop you start from 0 till 9 so you are playing with 10 elements of the array and not 9 (size of the array)
you should define the array with size 10
int vettore[10];
Arrays (i.e. "vectors") start at index zero NOT one; it's contents may be, for example, 5 but it will occupy index locations of 0,1,2,3,4....
[1][2][3][4][5] <- Five items
0 1 2 3 4 <- Their respective locations in the array
Same goes for visualizing characters in strings.....(technically the location in memory contains ASCII value-- look into that for fun ;) )
['c']['a']['t'] <- Three items
0 1 2 <- Their index location in the array
I suggest Kochan's C Programming book; great for starting out!!!

Resources