C++ program hangs due to a `uint32_t` for-loop - c++

I have the following program (this is it in its entirety, except comments):
#include <iostream>
#include <vector>
void sieve(uint32_t n) {
for(uint32_t i = 0; i < n; i++) {
for(uint32_t j = i * i; j < n; j += i) {
}
}
}
int main(int argv, char * argc[]) {
sieve(10);
return 0;
}
It compiles just fine. When I run it, it just hangs forever. Even if I put std::cout << "Test" as the first line in main, it never prints.
Am I missing something obvious here?

for(uint32_t j = i * i; j < n; j += i) {
First time through i is 0 and so j doesn't actually change (j += 0) ==> infinite loop

Related

OMP for loop condition not a simple relational comparison

I have this program that isn't compiling due to error: condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', '>=', or '!=') of loop variable 'i', referring to for (size_t i = 2; i * i <= n; i++). How can I modify and fix it without affecting performance? Is this an issue due to having an old OpenMP version? (Because I remember having a different issue before on another computer with an older version that is resolved now.)
#include <iostream>
#include <cstdio>
int main(int argc, char **argv)
{
if (argc != 2)
return EXIT_FAILURE;
size_t n;
if (sscanf(argv[1], "%zu", &n) == 0)
return EXIT_FAILURE;
auto *prime = new size_t[n + 1];
for (size_t i = 2; i <= n; i++)
prime[i] = i;
#pragma omp parallel for
for (size_t i = 2; i * i <= n; i++)
for (size_t j = i * i; j <= n; j += i)
prime[j] = 0;
size_t N = 0;
for (size_t i = 2; i <= n; i++)
if (prime[i] != 0)
N++;
std::cout << N << '\n';
}
Loop after the #pragma omp parallel for have to be a canonical form to be confirming. In your case the problem is with the test expression, which should be one of the following:
var relational-op b
b relational-op var
So, you have to use what was suggested by #Yakk: calculate the sqrt of n and compare it to i:
const size_t max_i=sqrt(n);
#pragma omp parallel for
for (size_t i = 2; i <= max_i; i++)
....

Runtime error for UVA Judge Online with C++ (Problem 10050)

Hi im having a problem with my program and i honestly dont know where or how to solve it. Here is the code
#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <iomanip>
#include <stdio.h>
#include <string.h>
using namespace std;
int main()
{
bool ok;
int testcases;
scanf("%d", &testcases);
vector<int> days(testcases);
vector<int> parties(testcases);
vector<vector<int>> hartals(2);
for (int i = 0; i < testcases; i++)
{
scanf("%d", &(days[i]));
scanf("%d", &parties[i]);
hartals[i].resize(parties[i]);
for (int j = 0; j < parties[i]; j++)
{
scanf("%d", &hartals[i][j]);
}
}
vector<vector<int>> initialHartalsValues = hartals;
for (int i = 0; i < testcases; i++)
{
int week = 0, nonWorkingDays = 0;
for (int j = 1; j < days[i] + 1; j++)
{
if (j != 1 && j - 7 * (week + 1) == 1)
{
week++;
}
ok = true;
for (int k = 0; k < hartals[i].size(); k++)
{
if (hartals[i][k] == j)
{
hartals[i][k] = hartals[i][k] + initialHartalsValues[i][k];
if (ok && j - 7 * week != 6 && j - 7 * week != 7)
{
ok = false;
nonWorkingDays++;
}
}
}
}
printf("%d\n", nonWorkingDays);
}
return 0;
}
The program works fine and it does its job but when i submit it to the judges i throws a runtime error and i cant find where it is.
vector<vector<int>> hartals(2);`
Constructs two entries in the outer vector and no entries in the inner vectors`.
But then we have
for (int i = 0; i < testcases; i++)
{
...
hartals[i].resize(parties[i]);
testcases probably isn't 2, so i can easily be out of bounds and invoke the dreaded Undefined Behaviour. On your machine the program manifests behaviour that appears to "work". On the judging system, you have better luck and the program crashes. Strange as it sounds, crashes are good luck. With a crash you know you have a bug.
Give
vector<vector<int>> hartals(testcases);
a test and see if it helps out. Could be more bugs in there, but that's probably the one you're tripping over right now.

making arr[n][n] with new-expression in C++

I am currently working on this code. But there are some problems. First of all, if I run this code, it says array size in new-expression must be constant. If I make the array arr[n], this error message does not appear. Also this code makes error message when it gets to the line cout << arr[i][j] << endl; saying that invalid types 'int[int]' for array subscript. I do not understand why this error message comes out because I made the array arr[n][n] not arr[n].
What I want to make with this code is showing the magic-square for n*n if I type in n in the argument line.
This is my main.cc
#include <iostream>
#include <cstdlib>
#include <cstring>
#include "magic_square.h"
using namespace std;
int main(int argc, const char** argv) {
int n = atoi(argv[1]);
int *arr = new int[n][n];
if (n % 2 == 0 || n < 3)
return 0;
else
magicSquare(n, arr);
for (int i = 0, j = 0; i < n, j < n; i++, j++)
cout << arr[i][j] << endl;
delete[] arr;
return 0;
}
This is my magic_square.cc. I did not add magic_square.h as it is only the declaration of the funtion void magicSquare(int n, int* arr).
#include <iostream>
#include "magic_square.h"
void magicSquare(int n, int* arr) {
for (int i = 0, j = n/2, num = 1; num <= n*n; num++) {
arr[i][j] = num;
if (num % n == 0) {
i++;
}
else {
i--, j++;
if (i < 0)
i = n - 1;
if (j > (n - 1))
j = 0;
}
}
}
~
Can anybody help me with this errors? Thanks in advance!
Take account that the for condition is just working because the two comma separated expressions are true at the same time.
for (int i = 0, j = 0; i < n, j < n; i++, j++)
That end condition is equivalent to only do the last test, since its result will be the result of the comma separated expression.
Probably you should have written this:
for (int i = 0, j = 0; i < n && j < n; i++, j++)

How to construct a compound for loop in C++?

Is another for loop allowed in the counter section (third part) of a for loop? In my attempt to get elegant in writing code to produce a right triangle, I wrote this but it wouldn't compile:
#include <stdio.h>
int main()
{
int i, j, N = 5;
for (i = 1;
i <= N;
(for (j = 1; j <= i; j++, printf("%c", '0'));), i++)
printf("\n");
}
return 0;
}
No there are allowed only expressions or declarations.
EDIT: I am sorry. I thought you are speaking about the condition part of the loop. In the expression part of the loop there are allowed only expressions.
You could use a lambda expression that would contain this for loop. For example
for ( i = 1;
i <= N;
[]( int i ) { for ( j = 1; j <= i; j++, printf("%c", '0' ) ); }( i ), i++)
Here is a demonstrative example
#include <iostream>
int main()
{
int N = 10;
for ( int i = 1;
i < N;
[]( int i )
{
for ( int j = 1; j < i; j++, ( std::cout << '*' ) );
}( i ), i++ )
{
std::cout << std::endl;
}
return 0;
}
The output is
*
**
***
****
*****
******
*******
********
Or your could define the lambda expression outside the outer loop that to make the program more readable. For example
#include <iostream>
int main()
{
int N = 10;
auto inner_loop = []( int i )
{
for ( int j = 1; j < i; j++, ( std::cout << '*' ) );
};
for ( int i = 1; i < N; inner_loop( i ), i++ )
{
std::cout << std::endl;
}
return 0;
}
Take into account that in general case the nested loops showed in other posts are unable to substitute the loop with the lambda-expression. For example the outer loop can contain continue statements that will skip the inner loop. So if you need that the inner loop will be executed in any case independing on the continue statements then this construction with the lambda expression will be helpful.:)
There is no need to do so. Because for loop can be easily replaced with while loop, every part of for loop can be placed in another place, where it's possible to use complex constructions. In your case, you can just change loop to the following:
for (i = 1; i <= N; i++) {
printf("\n");
for (j = 1; j <= i; j++) {
printf("%c", '0');
}
}
However, if you really have to place complex action, you may use gcc extension (compound statement):
for (i = 1;
i <= N;
({for (j = 1; j <= i; j++) putchar('0'); }), i++) {
printf("\n");
}
In the counter section of a for() loop, expressions are allowed, but statements are not.
And every for() line in C/C++ forms a new statement (it's not an expression).
However, you can nest several for() loops if you want.
For example, since you want a new loop in the counter sections, that means that you need to perform a loop at the end of the main for() loop.
This is the scheme:
for (int i = 0; i < i_max; i++) {
// stuff...
for (int j = 0; j < j_max; j++) {
// stuff..
}
}
You can't do that because condition and increment parts of a for can only contain expressions. A for loop is an iteration statement, though.
Simply nest the loops like sane programers do:
#include <stdio.h>
int main()
{
int N = 5;
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= i; j++)
printf("0");
printf("\n");
}
}
If you're not feeling well, though, you could use a lambda:
#include <stdio.h>
int main()
{
int N = 5;
for (
int i = 1;
i <= N;
[=](){ for (int j = 1; j <= i; j++) printf("0"); }(), printf("\n"), i++
) ;
}
Shortest-possible solution:
main(i){for(i=1;i<11;printf("%0*d\n",i++,0));}
Output:
0
00
000
0000
00000
000000
0000000
00000000
000000000
0000000000
LIVE DEMO
Elegance comes with clarity.
When I want to create a string of characters, I construct a C++ object called std::string.
#include <iostream>
#include <string>
int main()
{
char c = '0';
const int n = 5;
for (int i = 1; i <= n; ++i)
{
std::cout << std::string(i, c) << '\n';
}
}
So there is no need for a nested for-loop in this particular case.
Otherwise put a for-statement in the body of the outer loop as other answers suggested.
Hat tip to Michael Burr for the suggestion to use lambda. And thanks to the commentators requesting me to use putchar().
#include <stdio.h>
int main() {
int N;
scanf("%d", &N);
for (int i = 0; i < N; i++, [i] {
for (int j = 1; j <= i; j++, putchar('0'))
;
}(), printf("\n"))
;
return 0;
}
LIVE DEMO
I think we should avoid obfuscated code unless we get paid for making the code complex.

Matrix Multiplication Using win32 threads

I have no idea what's wrong with my code ... It always return zeros in all the elements. A hint of where is the problem would be great :)
#include <iostream>
#include <stdio.h>
#include <cstdlib>
#include <ctime>
#include <windows.h>
using namespace std;
int nGlobalCount = 0;
int thread_index = 0;
int num_of_thr=5;
int a[4][4], b[4][4], c[4][4];
int i, j, k;
struct v {
int i; /*row*/
int j; /*column*/
};
DWORD ThreadProc (LPVOID lpdwThreadParam ) {
//
struct v *input = (struct v *)lpdwThreadParam;
int avg=4*4/num_of_thr;
int count=0;
for(int i = 0; i <= 3 ; i++) {
for(int j = 0; j <= 3; j++) {
int sum=0;
for ( k = 0 ; k <= 3; k++) {
sum=sum+((a[input->i][k])*(b[k][input->j]));
c[input->i][input->j]=sum;
count++;
}
}
}
//Print Thread Number
//printf ("Thread #: %d\n", *((int*)lpdwThreadParam));
//Reduce the count
return 0;
}
int main() {
// int x=0;
cout<<"enter no of threads : ";
cin>>num_of_thr;
DWORD ThreadIds[num_of_thr];
HANDLE ThreadHandles[num_of_thr];
//struct v {
// int i; /*row*/
// int j; /*column*/
//};
struct v data[num_of_thr];
int i , j , k;
for ( int i = 0 ; i <= 3; i++) {
for (int j = 0 ; j <= 3 ; j++) {
a[i][j] = rand() % 10;
b[i][j] = rand() % 10;
c[i][j] = 0;
}
}
for(int i = 0; i < num_of_thr/2; i++) {
for(int j = 0; j < num_of_thr/2; j++) {
data[thread_index].i = i;
data[thread_index].j = j;
ThreadHandles[thread_index] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&ThreadProc, &data[thread_index], 0,&ThreadIds[thread_index]);
thread_index++;
}
}
WaitForMultipleObjects(num_of_thr, ThreadHandles, TRUE, INFINITE);
cout<<"The resultant matrix is "<<endl;
for ( i = 0 ; i < 4; i++) {
for ( j = 0 ; j < 4 ; j++)
cout<<c[i][j]<<" ";
cout<<endl;
}
for (int i=0; i<num_of_thr; i++)
CloseHandle(ThreadHandles[i]);
return 0;
}
At a GLANCE, your sum declaration in the loop looks sketchy.
for(int i = 0; i <= 3 ; i++) {
for(int j = 0; j <= 3; j++) {
for ( k = 0 ; k <= 3; k++)
{
int sum=sum+((a[input->i][k])*(b[k][input->j])); // this declaration seems wrong
c[input->i][input->j]=sum;
count++;
}
}
}
Each inner loop you redeclare sum, effectively making it 0. You might want to move the declaration up one or two loops from the assignment depending on what you are trying to achieve.
Do you realise that you have two separate sets of variables named a, b and c? One is local to the function main, and the other is a static for the whole program. I suspect that this is not what you intended. Try deleting the one that is local to main.
Martyn
A few things I found while poking about in addition to the other issues noted previously:
What are you compiling this with? With VC++ 2010 it "works", as in it outputs non-zeroes, although it complains about the DWORD ThreadIds[num_of_thr]; array declaration with a non-constant array size (I just made num_of_thr a constant and commented out the cin to test it quickly).
Are you sure you are inputting a valid number of threads with cin >> num_of_thr; For example, if num_of_thr was 0 this would explain the zeroes output. A simple cout here for num_of_thr would be useful.
In your data initialization loop starting with for(int i = 0; i < num_of_thr/2; i++) { you are not correctly counting threads which will result in an array underflow or overflow. For example, if num_of_thr is 5 then num_of_thr/2 is 2 which results in initializing only the elements 0..3 leaving the last element uninitialized. An array underflow is technically ok although the later CloseHandle() call will fail when it tries to free an essentially random handle. If you enter a larger number of threads you will overflow all your arrays (try it with num_of_thr=10 for example).
If it still doesn't work try removing the threading to see if the threading or code itself is the source of the problem. For example, you can call the ThreadProc() function manually in a loop instead of from within threads. Either trace through the program with a debugger or output logs to stdout/file (which would also work in the threading model).
Instead of a random source matrix I would use a few fixed values at first with a known result. This will make it easier to determine if the code is actually computing the correct result.