0

I was doing a programming question and was using freopen to redirect the streams. The problem I am facing is that the printf command is not printing on the output file after stdout redirection. I even tried using fflush but couldn't get any results.

Here is my code

    #include<iostream>
    #include<vector>
    #include<cmath>
    #define fc(a) static_cast<float>(a)
    using namespace std;
    
    vector<int>* touch(const vector<int> arr[], int size)
    {
        vector<int>* touch_circles = (vector<int>*)malloc(sizeof(vector<int>)*size);
        int i1, i2, dis;
        for(i1 = 0; i1 < size; i1++)
        for(i2 = i1+ 1; i2 < size; i2++)
        {
            dis = static_cast<int>(ceil(pow(pow(fc(arr[i1][0]) - fc(arr[i2][0]),2) + pow(fc(arr[i1][1]) - fc(arr[i2][1]),2),0.5)));
            if (dis <= arr[i1][2] + arr[i2][2])
            {
                touch_circles[i1].push_back(i2);
                touch_circles[i2].push_back(i1);
            }
        }
        return touch_circles;
    }
    
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("D:\\C++\\input.txt","r",stdin);
        freopen("D:\\C++\\output.txt","w",stdout);
        freopen("D:\\C++\\output.txt","w",stderr);
        #endif
        int t, x, y, n;
        int itr, i, i1, i2;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d %d %d", &x, &y, &n);
            vector<int> arr[n];
            for(itr = 0; itr < n; itr++)
            {
                scanf("%d %d %d", &i1, &i2, &i);
                arr[itr].push_back(i1);
                arr[itr].push_back(i2);
                arr[itr].push_back(i);
            }

            //The 'fflush'es are just for trial, problem persists with or without any of them
            fflush(stdout);
            vector<int> *touch_list = touch(arr, n);
            fflush(stdout);
            printf("Expected");
            fflush(stdout);
        }
    }

Here is my input.txt

1
20 10
2
10 7 2
10 4 2

My ouput.txt is empty. The code compiles fine and there are no errors, it just runs and finishes without printing anything on the output file. One weird thing is that the output is printed on ouput.txt if I comment out the function call from main. I don't understand why it happens as I don't think there is anything inside the function that could possibly affect the file streams. Any help is appreciated, I'm totally out of ideas now!

Dhruv
  • 117
  • 11
  • 1
    Have you tried commenting out `freopen` for `stderr`? – Semyon Burov Jan 14 '22 at 13:09
  • Tried right now but still nothing on output.txt – Dhruv Jan 14 '22 at 13:20
  • 1
    Don't use `scanf()` on user input without checking return value; you may be looking at uninitialized values. Why are you using C I/O (without actually including the relevant header...) in the first place when doing C++? Would you welcome an actually C++ answer? – DevSolar Jan 14 '22 at 13:21
  • Why use a macro? Why include `iostream` when you don't use it? (And IMHO you should use it). Why not use `fstream`? Why `using namespace std;`? Why not use constructors? Why use a pointer to a vector, instead of local object (with RVO)? This is C++, not C. – JHBonarius Jan 14 '22 at 13:32
  • @ Dev Solar, I thought C I/O would be faster so I was using that, is that wrong? – Dhruv Jan 14 '22 at 14:33
  • @ JHBonarius I am trying to shift to CPP and will definitely work on your advice, but I didn't want to create a local object because it would be destroyed after function call returns so I was dynamically allocating it. So is that fine? – Dhruv Jan 14 '22 at 14:36
  • @Dhruv: Not wrong, but error-prone, and not really C++. You sacrifice type safety and exception safety, for a dubious and unproven claim to "being faster", which in 99% of cases does not really matter because 99% of code isn't even performance-critical. Readable, idiomatic code should always be your first choice. – DevSolar Jan 17 '22 at 10:42

2 Answers2

1

Disclaimer: it may not be a true answer, and is certainly not the expected answer. But it is the most I can do here, and it would not fit in a comment...


It is time to find a good tutorial on C++...

This instruction is terrible:

    vector<int>* touch_circles = (vector<int>*)malloc(sizeof(vector<int>)*size);
  1. you should never use malloc in C++, because it only allocates memory but does not construct the objects. You should only use new and even new should be only be used with extreme caution
  2. it does not make sense to dynamically allocate a vector. A vector is a container that takes care of dynamic allocation for the objects it will contain
  3. unless for special use cases, you should avoid to use raw pointer in C++. Returning a pointer to a dynamically allocated object is a code smell.

That is not all. Vectors are arrays of variable size. When you have a compile time constant size, you should use a std::array.

Said differently, your current code consistently uses the bad container: raw arrays or pointers where you should use vectors and vectors where you should use a std::array.

This is really too terrible code for me to understand what you are trying to do and help you to fix it. Please write it in acceptable C++ in a new question.

I do not want to be offensive here. I just want to advise you to learn good practices, because it is really essential if you want to learn C++.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • thanks for your advice. I had some more doubts, I was trying to allocate an array of vectors not a vector in the function and then return it without destroying it (that's why I was dynamically allocating it, cause that's the only method I know). So is it safe to use new there? Also, I am trying to solve a competitive programming question so making classes and using objects would slow down the code I think. That's why I was using functions and pointers. Is there any substitute to that or am I wrong somewhere? – Dhruv Jan 14 '22 at 14:29
  • 1
    @Dhruv: competitve programming is the worst way to learn programming. Many high rep users here believe that because on line judges only look at the efficiency while what matters in real world (professional grade) programming is readability, robustness and maintainability. Only if you are fluent enough in a programming language, you should use those online judges to control/improve your algorithmic knowledge. But currently you should focus on writing correct C++ code and respect best practices. – Serge Ballesta Jan 14 '22 at 14:48
  • 1
    To more directly answer your question, using classes and objects will not necessarily slow down anything, or not in a noticiable way if any. Optimizing compilers are used to that, and **they** take care of low level optimization, while programmers should not. Learning is hard, and my advice is to respect the step order: learn first to write correct code, and only then and when profiling shows that it is required use C language constructs. – Serge Ballesta Jan 14 '22 at 14:54
  • @Dhruv: When you worry about the performance of creating / destroying when returning from a function, realize this: An object of type `std::vector` is only a few bytes. You have the size, the capacity, and a pointer to allocated memory. When you return that from a function, even **if** the compiler should have been unable to optimize away the copy-on-return, what gets copied are just those few bytes. The allocated memory would get transferred from the local `vector` to the returned `vector` via move semantics. Bottom line: Only attempt to optimize when you *know* you have a problem. – DevSolar Jan 17 '22 at 10:55
0

The code like yours produces pointer to uninitialised memory cast into pointer of vector:

vector<int>* touch_circles = (vector<int>*)malloc(sizeof(vector<int>*)*size);

That is just undefined behaviour to use such vectors also the memory alloated is likely insufficient. It probably crashes or hangs your program and no output is produced. Do not use malloc in C++ code like that. If you need raw array of vectors then write:

vector<int>* touch_circles = new vector<int>[size];

Or even better have vector of vectors.

Öö Tiib
  • 10,809
  • 25
  • 44
  • @ Oo Tiib I got your point and the code worked. Could you tell more on what goes wrong when using uninitialized memory with vectors like the logic behind it or some reference to a documentation. Also, I tried the using calloc which initializes memory on allocation and the code worked, so can I use calloc for allocation? – Dhruv Jan 14 '22 at 13:57
  • No. Vectors are class objects, you should not use just zero-initialised memory for those either. That way these are not properly constructed and even if appear to work with certain compiler options and other circumstances can fail with others. The new like I wrote runs all constructors of vectors so you should use new. – Öö Tiib Jan 14 '22 at 14:01