Why doesn't my freopen function work? - gcc

#include <stdio.h>
#include <string.h>
#define MAXN 15
char forbid[MAXN][MAXN];
int dp[2][1<<MAXN],c[1<<MAXN],*dp1,*dp2;
int cnt_one(int x)
{
int s=0;
while(x)
{
s++;
x&=x-1;
}
return s;
}
int main()
{
int t,n,s,a,b,i,j,k;
/*This is my use of freopen function*
************************************/
freopen("datain.txt","r",stdin);
freopen("dataout.txt","w",stdout);
/*This is just a dynamic program to solve a mathematical problem*
****************************************************************/
for(i=0;i<(1<<MAXN);i++) c[i]=cnt_one(i);
scanf("%d",&t);
while(t--)
{
memset(forbid,0,sizeof(forbid));
memset(dp[0],0,sizeof(int)*(1<<MAXN));
dp[0][0]=1;
scanf("%d%d",&n,&s);
while(s--)
{
scanf("%d%d",&a,&b);
forbid[a][b]=1;
}
for(i=1;i<=n;i++)
{
if(i%2)
{
dp1=dp[0];
dp2=dp[1];
}
else
{
dp1=dp[1];
dp2=dp[0];
}
memset(dp2,0,sizeof(int)*(1<<MAXN));
for(j=0;j<(1<<n);j++)
{
if(c[j]!=i-1) continue;
for(k=0;k<n;k++)
{
if(!(j>>k&1)&&!forbid[i][n-k]) dp2[j^(1<<k)]+=dp1[j];
}
}
}
printf("%d\n",dp2[(1<<n)-1]);
}
return 0;
}
This is my program.I used a dynamic program method to solve a mathematical problem.
But when I used the "freopen" function to redirect the "stdout" stream to the file of "dataout.txt",it failed and the file had no data in it.
Could you tell me why I can get the data from "datain.txt" but I can't output data into "dataout.txt"?Is there something wrong with my "freopen" function for "stdout" stream?

I think the problem is that you have a segmentation fault that you will not see. If you place a printf and a return after the freopen I think it will work (works for me).
I would recommend you to use "valgrind" on the resulting executable compiled for debug to see at what line the program crashes. If you want someone to help you further, you need to provide an example input.

Related

when i use typeid in template function cause error

here is code snippet i try to compile, which result to compile error:
convert const char * to int is invalid;
can anyone help debug this code ?
thanks in advance!
#include <iostream>
#include <typeinfo>
using namespace std;
int sums() { return 0; }
template <typename Type, typename... T>
int sums(const Type s, const T... args)
{
int res = 0;
if (typeid(s) == typeid(int))
{
res += s;
}
else
{
cout << "not int" << s << endl;
}
res += sums(args...);
return res;
}
int main()
{
cout << sums(1,"sir", 4) << endl;
return 0;
}
You try to do different things for different types, but a normal if in combination with typeid is evaluated at runtime. That mean that the compiler must generate code for both cases, because the evaluation which is executed is not clear at compiler time.
To fix this problem you must bring the decision from runtime to compile time.
Thats what if constexpr is for. It is evaluated at compile time and there you can write code in one branch that would not compile if the condition is not fulfilled

Data Structures Simple Text Editor

I'm really new to DSA or basically just finished learning about Data Structures.
Tried this Hacker Rank problem (https://www.hackerrank.com/challenges/simple-text-editor/problem?isFullScreen=true) after solving a few of them already.
The problem here is after pushing a the first element in Stack, All the elements after that first element gets changed to the last added element.For e.g->
Push-> abcde,
Push-> de,
Push-> c,
Push-> ab
All the elements ab,c,de after abcde change to ab for some unknown reason.
I know there are/will be many simpler approaches than this one but I just wanna know what is wrong here.Any help would be appreciated since I'm a beginner. Thank you :)
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
struct Stack
{
char *arr[100][100];
int tos;
};
void push(struct Stack*,char*);
char *pop(struct Stack*);
int main() {
int i,place,j,Q,c;
char warr[100],Str[1000]="";
struct Stack S1,S2;
S1.tos=S2.tos=-1;
scanf("%d",&Q);
for(i=0;i<Q;i++)
{
scanf("%d",&c);
if(c==1)
{
fflush(stdin);
scanf("%s",warr);
strcat(Str,warr);
push(&S2,"1");
push(&S1,warr);
}
else if(c==2)
{
int k=0;
char warr[100]="";
scanf("%d",&place);
for(j=strlen(Str)-place;j<strlen(Str);j++)
{
warr[k]=Str[j];
k++;
}
warr[k]='\0';
push(&S2,"2");
push(&S1,warr);
Str[strlen(Str)-place]='\0';
}
else if(c==3)
{
scanf("%d",&place);
printf("%c\n",Str[place-1]);
}
else
{
if(strcmp(pop(&S2),"1")==0)
{
Str[strlen(Str)-strlen(pop(&S1))]='\0';
}
else
{
char *ch;
ch=pop(&S1);
strcat(Str,ch);
}
}
printf("string=%s\n",Str);
}
return 0;
}
void push(struct Stack *S,char *arr)
{
S->tos=S->tos+1;
S->arr[S->tos][99]=arr;
printf("pushed=%s\n",S->arr[S->tos][99]);
}
char* pop(struct Stack *S)
{
char* arr;
arr=S->arr[S->tos][99];
printf("popped=%s\n",S->arr[S->tos][99]);
S->tos=S->tos-1;
return arr;
}

STD::FUNCTION C++

I'm still learning Modern C++ and I would like to clarify STD:FUNCTION,
Here is my sample code that works fine :
#include <iostream>
#include <functional>
using namespace std;
int func(function<bool()> foo) {
return 2;
}
struct fee {
bool operator()() {
return true;
}
};
int main() {
cout << func(fee());
}
It will display "2" on the console.
What I am wondering is why this does not work. I changed bool operator()() to bool operator()(int i).
#include <iostream>
#include <functional>
using namespace std;
int func(function<bool()> foo) {
return 2;
}
struct fee {
bool operator()(int i) {
return true;
}
};
int main() {
cout << func(fee());
}
The error says:
In function 'int main()':
18:20: error: could not convert 'fee()' from 'fee' to 'std::function<bool()>'
What should be the right thing to do ?
In the second example, the fee operator() function now takes an int as a parameter.
Therefore you need to change
int func(function<bool()> foo) {
return 2;
}
to
int func(function<bool(int)> foo) {
return 2;
}
to reflect that.

Put c++ iterator into queue

Is there any problem to put c++ iterator into queue? For example:
vector<vector<int>> vecs;
queue<pair<vector<int>::iterator, vector<int>::iterator>> mq;
for (auto &e : vecs)
{
mq.push(make_pair(e.begin(), e.end()));
}
Iterators may be invalidated if you modify the variable vecs.
For more details, refer to iterator invalidation rules.
#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
#include<utility>
using namespace std;
vector<vector<int>> vecs;
queue<pair<vector<int>::iterator, vector<int>::iterator>> mq;
void populate_vector()
{
for(int i = 0;i<6;++i)
{
for(int j =0;j<6;++j)
{
vecs[i].push_back(i+j);
}
}
}
void print_queue()
{
queue<pair<vector<int>::iterator, vector<int>::iterator>> :: iterator qiter = begin(mq);qiter != end(mq);++qiter)
cout<<"*qiter.first"<<*qiter.first<<"*qiter.second"<<*qiter.second<<endl;
}
void print_vector_run_time_error(vector<vector<int>> cont){
try{
for(int i =0;i<6;++i)
{
for(int j =0;j<6;++j)
{
cout<<cont[i][j]<<" ";
}
cout<<endl;
}
}
catch(exception &e){
cout<<e.what();
}
}
int main()
{
for (auto &e : vecs)
{
mq.push(make_pair(e.begin(), e.end()));
}
/*
if the below 3 function calls were not present,compilation and running happens successfully .
This code creates problems at compile or run time as described below (whenever memory is accessed and iterators are invalidated).
*/
print_queue();
/*
gives a compile time error as the compiler does not recognize a call to vector<int>::iterator as iterator is not a container
*/
populate_vector();
/*
the above function compiles successfully but terminates at run time , because memory is accessed during run time to fill the
elements with a value(C++11 vector is populated always at run time).
*/
print_vector_run_time_error(vecs);
/* above function call to print vector compiles successfully , but terminates at run time
because memory is accessed at run time to print the value of the elements.
*/
return 0;
}
This code could give an explanation for the problem.

Simple multithreading mutex example is incorrect

I expect to get numbers from 0 to 4 in random order, but instead, I have some unsynchronized mess
What i do wrong?
#include <iostream>
#include <windows.h>
#include <process.h>
using namespace std;
void addQuery(void *v );
HANDLE ghMutex;
int main()
{
HANDLE hs[5];
ghMutex = CreateMutex( NULL, FALSE, NULL);
for(int i=0; i<5; ++i)
{
hs[i] = (HANDLE)_beginthread(addQuery, 0, (void *)&i);
if (hs[i] == NULL)
{
printf("error\n"); return -1;
}
}
printf("WaitForMultipleObjects return: %d error: %d\n",
(DWORD)WaitForMultipleObjects(5, hs, TRUE, INFINITE), GetLastError());
return 0;
}
void addQuery(void *v )
{
int t = *((int*)v);
WaitForSingleObject(ghMutex, INFINITE);
cout << t << endl;
ReleaseMutex(ghMutex);
_endthread();
}
You have to read and write the shared variable inside the lock. You are reading it outside of the lock and thus rendering the lock irrelevant.
But even that's not enough since your shared variable is a loop variable that you are writing to without protection of the lock. A much better example would run like this:
#include <iostream>
#include <windows.h>
#include <process.h>
using namespace std;
void addQuery(void *v );
HANDLE ghMutex;
int counter = 0;
int main()
{
HANDLE hs[5];
ghMutex = CreateMutex( NULL, FALSE, NULL);
for(int i=0; i<5; ++i)
{
hs[i] = (HANDLE)_beginthread(addQuery, 0, NULL);
if (hs[i] == NULL)
{
printf("error\n"); return -1;
}
}
printf("WaitForMultipleObjects return: %d error: %d\n",
(DWORD)WaitForMultipleObjects(5, hs, TRUE, INFINITE), GetLastError());
return 0;
}
void addQuery(void *v)
{
WaitForSingleObject(ghMutex, INFINITE);
cout << counter << endl;
counter++;
ReleaseMutex(ghMutex);
_endthread();
}
If you can, use a critical section rather than a mutex because they are simpler to use and more efficient. But they have the same semantics in that they only protect code inside the locking block.
Note: Jerry has pointer out some other problems, but I've concentrated on the high level trheading and serialization concerns.
Your synchronization has some issues as you want to get numbers from 0 to 4 in random order.
The problem is that the variable i is write outside the lock and every time the addQuery method get called by the execution of a thread, it get the modified version of variable i. That why you may see 5 as the value at the output for all.
So, here is my fix for this scenario. Instead of pass the address of variable i in parameters of the function addQuery, you should pass it's value. Hope it helps:
#include <iostream>
#include <windows.h>
#include <process.h>
using namespace std;
void addQuery(void *v);
HANDLE ghMutex;
int main()
{
HANDLE hs[5];
ghMutex = CreateMutex(NULL, FALSE, NULL);
for (int i = 0; i<5; ++i)
{
hs[i] = (HANDLE)_beginthread(addQuery, 0, (void *)i);
if (hs[i] == NULL)
{
printf("error\n"); return -1;
}
}
printf("WaitForMultipleObjects return: %d error: %d\n",
(DWORD)WaitForMultipleObjects(5, hs, TRUE, INFINITE), GetLastError());
return 0;
}
void addQuery(void *v)
{
int t = (int)v;
WaitForSingleObject(ghMutex, INFINITE);
cout << t << endl;
ReleaseMutex(ghMutex);
_endthread();
}

Resources