Why the first prime number always becoming 1 instead of 2 - c

Here i am trying to implement sieve of erastosthene in c.The program works fine except one major problem.I manually set the first prime number to be of value 2.But at the end when i loop through all the prime numbers array and print them ,the first value becomes 1 instead of 2.Can't figure out why this problem arises.Any help would be much appreciated.
#include<stdio.h>
#include<math.h>
int main(){
int n = 64;
int i,j,limit=sqrt(n)+2,nPrime=0;
int prime[50]={0},mark[64]={0};
mark[1]=1;
prime[nPrime++] = 2;
printf("%d\n",prime[0]); // initialized to 2
for(i=4;i<=n;i=i+2){
mark[i] = 1;
}
for(i=3;i<=n;i=i+2){
if(!mark[i]){
prime[nPrime++] = i;
if(i<=limit){
for(j=i*i;j<=n;j=j+i*2){
mark[j]=1;
}
}
}
}
int k;
int size = sizeof(prime)/sizeof(prime[0]);
printf("%d\n",prime[0]); // changed to 1;
for(k=0;k<size && prime[k]!=0;k++){
printf("%d ",prime[k]);
}
}

The problem is in this loop:
for(i=4;i<=n;i=i+2) {
mark[i] = 1;
}
The condition should be i < n, because with <= it will take the value 64, and that would be out of bounds.
When you set mark[64] = 1 you are modifying memory that does not belong to the mark array, in this case it turn out to be the first element of the prime array. If you test out other indexes, you could end up getting a segfault.
If you set manually mark[64] = 56, you will see that prime[0] == 56

Because local variable are declared on stack, in your case the variable mark[64] which is an array of 64 integer (64 * 4 = 256 bytes) occupies the first 256 bytes of the stack then the array prime (50 * 4 = 200 bytes) occupies the next 200 bytes as shown below:
Stack
|-----------|
| other |
| variables |
| |
prime[49]->|-----------| addr = 0x000001C8
| |
| prime |
|(200 bytes)|
prime[0]->| |
mark[63]->|-----------| addr = 0x00000100
| |
| |
| mark |
|(256 bytes)|
| |
mark[0]->|-----------| addr = 0x00000000
When you write mark[64] = 1, you are actually writing the four bytes of prime[0] = 1.

Related

Why my table is not displayed if I do not put it [i]

I would like to know what the [i] is for, and why my table is not displayed if I do not put it in.
Thank you!
#include <stdio.h>
void affiche(int* tableau, int taille);
int main()
{
int tableau[5] = { 12,15,50,20 };
affiche(tableau, 4);
return 0;
}
void affiche(int *tableau,int taille)
{
int i;
for (i = 0; i < taille; i++)`
{
printf("%d\n", tableau[i]);
}
}
[i] is the C language syntax for array notation.
tableau is an array of 5 integers.
int tableau[5] = {12,15,50,20}
In memory tableau has 5 slots allocated to it due to the above declaration.
Slots 0 through 3 are your initialization values.
Slot 4 is uninitialized (though modern c compilers might set this value to null or zero (0).
tableau
+-----------------------+
index | 0 | 1 | 2 | 3 | 4 |
+-----------------------+
value | 12 | 15 | 50 | 20 | ? |
+-----------------------+
inside function affiche(...) this statement
printf("%d\n", tableau)
tries to print to console a single integer (%d) followed by a newline (\n)
But tableau is an array of 5 integers.
So you need the array index to select a specific integer individually like this:
printf("%d\n", tableau[0]) // output: 12
printf("%d\n", tableau[1]) // output: 15
printf("%d\n", tableau[2]) // output: 50
printf("%d\n", tableau[3]) // output: 20
printf("%d\n", tableau[4]) // output: unknown, possible exception
or by function call to affiche(tableau, 4); which ends at index 3
void affiche( int *tableau, int taille)
{
int i;
for( i = 0; i < taille; i++){
printf( "%d\n", tableau[i] );
}
}
Which outputs:
12
15
50
20

How one malloc call for all rows work for 2D array?

I know that we can achieve dynamic multi-dimensional arrays using pointers and there are many ways to do it, with single pointers and double pointers as well. But while exploring on this topic, came across this piece of code in which I am not able to understand the head and tail. Can anyone please explain me how the below piece of code works?
Also please explain,
1) Why it is necessary to allocate r*sizeof(int*) to arr when we are anyways going to allocate memory to arr[i] as r*c*sizeof(int).
2) Why it is necessary to do arr[i] = *arr+c*i.
Since I am very new to this dynamic memory allocation and so much eager to dig little deeper, arised these questions. Sorry if it is basic but still I have no idea about it.
Thanks,
#include<stdio.h>
#include<stdlib.h>
int main()
{
int r=3, c=4;
int **arr;
int count = 0,i,j;
arr = (int **)malloc(sizeof(int *) * r);
arr[0] = (int *)malloc(sizeof(int) * c * r);
for(i = 0; i < r; i++)
arr[i] = (*arr + c * i);
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
arr[i][j] = ++count; // OR *(*(arr+i)+j) = ++count
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
{
printf("%d, %p, %p\n", arr[i][j], &arr[i][j], arr[i]);
}
return 0;
}
Output:
1, 21100, 21100
2, 21104, 21100
3, 21108, 21100
4, 2110c, 21100
5, 21110, 21110
6, 21114, 21110
7, 21118, 21110
8, 2111c, 21110
9, 21120, 21120
10, 21124, 21120
11, 21128, 21120
12, 2112c, 21120
Instead of allocating for each of the r pointers allocated in arr, only the first one is used to allocate memory for an rxc array. And rest of the pointers points to chunk of this memory.
Benefit can be that it is possible to use single memset to initialize the array. Freeing is much more easier (just free the first pointer's allocated memory).
arr[i] = (*arr + c * i); this is basically initializing the pointer arr[i] with the relevant section to which it should point to.
And from the start of the allocated memory where will that be?
There arr[0],arr[1]..arr[i-1] pointers which points to their rows which contains c elements each. So c elements each for i pointers - i*c elements all together is being addressed already. So the next one to be pointed by arr[i] will (*arr+c*i).
After OP edited the question:
OP asked why we need to do arr = (int **)malloc(sizeof(int *) * r) ?
I guess this picture explains a lot than words.
arr --> [0] [1] [2] [3] .....[r-2] [r-1]
| | | | | |
V | | | | |
[0] <-+ | | | |
[1] | | | |
[2] | | | |
[3] | | | |
[4] | | | |
. | | | |
| | | |
[c-1] | | | |
[c] <----+ | | |
[c+1] | | |
[c+2] | | |
. | | |
. | | |
. | | |
[2c] <----------+ | |
[2c+1] | |
[2c+2] | |
. | |
. | |
. | |
[(r-2)*c] <------------------+ |
[(r-2)*c+1] |
. |
. |
[(r-2)*c+(c-1)] |
[(r-1)*c] <----------------------+
[(r-1)*c+1]
[(r-1)*c+2]
[(r-1)*c+3]
[(r-1)*c+(c-1)]~[rc-1]
Those first row explains arr = malloc(sizeof(int *) * r);
You can see all allocated memory in the soingle column. Because that's what you did arr[0] = (int *)malloc(sizeof(int) * c * r);
And then the links explain arr[i] = (*arr + c * i);.
Check the thing, the links point to (*arr) also in pic [0]
and (*arr+c) in pic [c] and (*arr+2c) in pic [2c].
We need them because it is basically letting us get to the beginning of the correct address of the starting of each of the r rows.
The address are being calculated as offset from the beginning of the *arr.
If you didn't assign the addresses to arr[i] then you couldn't access the array like this arr[row][col] then you had to do arr[0][row*c+col] (You can see that image also says that thing).
This piece of code allocates two memory areas
arr able to contain r pointers to int
arr[0] area, for r * c int
(*arr + c * i) is same as &arr[0][c*i]
then each r (row) is assigned a pointer to a location in arr[0] spaced by c (column) int (to store c int)
for(i = 0; i < r; i++)
arr[i] = (*arr + c * i);
graphically (with r == 3, and c == 4), P pointer, I integer
arr: 0:P 1:P 2:P
| | |
v v v
arr[0]: IIIIIIIIIIII
then it just treats the array as a arr[row][col]
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
arr[i][j] = ++count;
In C, arrays are stored in "row major" order in memory. That means in a two dimensional array elements in the same row are adjacent to I've another in memory, and so elements in the same column are spaced apart by the number of columns (i.e the row width).
*arr gives you back a pointer to an int because it is dereferencing a pointer to a pointer to an int. Specifically it is the pointer pointed to by the name arr. That is the base address of the array.
arr[i] is also a pointer to an int. Now remember what I said about row major. Where should i-th row pointer point? The answer is, at the base of the array (*arr) plus i times the number of columns (c). The loop that confuses you is merely making the others point at the right places so that implied pointer arithmetic works when it comes time to use arr[r][c] notation.
Voila.

How does odd number print increasing order?

#include <stdio.h>
#include<string.h>
void Magic(int in);
int Even(int n);
int main()
{
Magic(10);
}
void Magic(int in)
{
if(in == 0)
{
return;
}
if(Even(in))
{
printf("%i\n", in);
}
Magic(in - 1);
if(!Even(in))
{
printf("%i\n", in);
}
return;
}
int Even(int n)
{
return (n % 2) == 0 ? 1 : 0;
}
how does odd number print in increasing order?
It prints 10 8 6 4 2 1 3 5 7 9.
I know upto 10 8 6 4 2 but how come it prints 1 3 5 7 9? after decreasing order?
There are nested calls Magic(in - 1);. If number is even it is printed immediately and then Magic(in - 1); is called. Only when n is zero all functions print not even number in reverse order. The first odd number is printed by the deepest Magic() function:
Magic(10)
|print 10
|Magic(9)
| |Magic(8)
| | print 8
| | ...
| | Magic(1)
| | Magic(0)
| | return;
| | print 1
| | return
| | ...
| | return
| |print 9
| |return
|return
this is caused by the recursion of the function. the function is returning in the order it was called. if you want to print the odd numbers in decreasing order after the even numbers, you need to save them in a variable (array ) that is also passed to the magic function

Removing the leading zeroes of a number stored in string

struct number {char digits[11];};
The following method removes leading zeroes from (*a).digits
void remove_zero(struct number *a);
Example: (*a).digits 000013204 ---> 13204
My approach is to define a variable b equals to (*a).digits, start seaching for the first non-zero number in b, then replace (*a).digits with the rest of b. However, I am having trouble implementing the code
void remove_zero(struct number *a) {
char b = (*a).digits;
while (b){ // <--- (b) indicates that it hasnt reached the terminator,right?
if (b != '0')
{ //<-- here is where to replace (*a).digits with the rest of b, but how to?
break;
}
}
}
So you have an array that contains e.g.
+---+---+---+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 1 | 3 | 2 | 0 | 4 | \0| |
+---+---+---+---+---+---+---+---+---+---+---+
And you want it to contain
+---+---+---+---+---+---+---+---+---+---+---+
| 1 | 3 | 2 | 0 | 4 | \0| | | | | |
+---+---+---+---+---+---+---+---+---+---+---+
From the "images" above, it should be pretty clear that this can be done using a simple movement of the data.
So one solution is to find the first non-zero character, and move from that to the beginning of the array.
In general it's clearer to deference a pointer to a struct and access its attributes using the -> operator, e.g. rather than
char b = (*a).digits;
do this
char *b = a->digits;
Note that digits is an array of chars, so b needs to be an array of chars, or a pointer to a char as shown here.
So:
void remove_zero(struct number *a)
{
char *b = a->digits;
char *end = a->digits + sizeof a->digits - 1;
while (b < end && *b == '0')
b++;
if (b != a->digits)
{
size_t n = end - b;
memmove(a->digits, b, n);
a->digits[n] = '\0';
}
}

Solving #1015 (Brush) in LightOJ

I am trying to solve the following problem.
Input
Input starts with an integer T (≤ 100), denoting the number of test cases.
Each case starts with a blank line. The next line contains an integer N (1 ≤ N ≤ 1000), means that there are N students. The next line will contain N integers separated by spaces which denote the dust unit for all students. The dust unit for any student will not contain more than two digits.
Output
For each case print the case number and the total required dust units.
Sample Input
+--------------+-------------------------+
| Sample Input | Output for Sample Input |
+--------------+-------------------------+
| 2 | Case 1: 16 |
| | Case 2: 100 |
| 3 | |
| 1 5 10 | |
| | |
| 2 | |
| 1 99 | |
+--------------+-------------------------+
Here is my code:
#include <stdio.h>
int main() {
int kase = 0;
int i = 0, j = 0;
do {
scanf("%d", &kase);
} while (kase > 100);
int group[kase];
int tdust[kase];
for (i = 1; i <= kase; i++) {
tdust[i] = 0;
printf("\n");
do {
scanf("%d", &group[i]);
} while (group[i] < 1 || group[i] > 1000);
int stdNumber[group[i]];
for (j = 1; j <= group[i]; j++) {
do {
scanf("%d", &stdNumber[j]);
} while (stdNumber[j] >= 100);
tdust[i] = tdust[i] + stdNumber[j];
}
}
for (i = 1; i <= kase; i++)
printf("\nCase %d: %d", i, tdust[i]);
}
When I submit my code, OnlineJudge says I've got the wrong answer. How can I fix it?
You are getting WA because your code exhibits UB(Undefined Behaviour). You assume that the valid indices for an array of length n where n is a natural number, starts from 1 and ends at n. That is wrong.For an array of length n(n is a natural number), Array indices start from 0 and end at n-1.
To fix it, change
for(i=1; i<=kase; i++)
To
for(i=0; i<kase; i++)
And similarly,do the same for all the other loops. Also change
printf("\nCase %d: %d",i,tdust[i]);
To
printf("\nCase %d: %d",i+1,tdust[i]);
So that you get the desired result.

Resources