Search code examples
c++stlglobal-variablesstdvectordouble-free

Double free error/ corruption in C++ while using globally declared vectors


For this code,

#include<bits/stdc++.h>
#include<iostream>
#include<vector>

using namespace std;

vector<long long int> v1,v2;

    int main(int argc, char const *argv[]){
        long long int t, n, i, x, day_count;
        scanf("%llu", &t);
        while(t--){
            scanf("%llu", &n);
            for(i=0; i<n; i++){
                scanf("%llu", &x);
                v1.push_back(x);
                v2.push_back(0);
            }
            day_count = SpreadTheWord(n);
            printf("%llu\n", day_count);    
            v1.clear();
            v2.clear();
        }  
        return 0;
    }

I'm getting the output I want but after the main executes 'return 0', I get this error

*** Error in `./a.out': double free or corruption (!prev): 0x0000000001d62e20 ***

I got the answer using another code, but I want understand why this code gets this error.

I don't think anything is wrong with SpreadTheWord(), but just in case you want to see what SpreadTheWord() does

long long int SpreadTheWord(long long int n){
    long long int dc = 0;
    long long int i = 0, j, m;
    j = i + 1;
    long long int k = v1[i];
    v2[i] = 2;
    while(true){
        if(v2[n-1] == 2){ //condition 1
            return dc;
        }
        if(k!=0 && v2[i] == 2){ //condition 2
            v2[j] = 1;
            k--;
            j++;
        }
        else if(k==0){ //condition 3
            i++;
            if(v2[i] == 2)  //condition 3.1
                k = v1[i];
            else{               //condition 3.2
                m= 0;
                while(v2[m] != 0){
                    v2[m] = 2;
                    m++;
                }
                i = 0;
                dc++;
                k = v1[i];
            }
        }
    }
    return dc;
}

Thank you!

EDIT : Sorry, I forgot to attach the input

3
10
1 1 1 1 1 1 1 1 1 1
10
2 2 2 2 2 2 2 2 2 2
10
3 3 3 3 3 3 3 3 3 3 

The problem was from here : https://www.codechef.com/SNCKQL19/problems/SPREAD2


Solution

  •             while(v2[m] != 0){
                    v2[m] = 2;
                    m++;
                }
        if(k!=0 && v2[i] == 2){ //condition 2
            v2[j] = 1;
            k--;
            j++;
        }
    

    Proving that v2[j] and v2[m] are always within the bounds of v2 is non-trivial.

    In general, SpreadTheWord is a pile of spaghetti logic and is probably corrupting the heap.


    Replace [x] with .at(x) to get exceptions rather than memory corruption.

    Declare variables as close to their initialization as possible, and have them fall out of scope as soon as possible, to reduce the length variables hang around and reduce the amount of "state" programs have.

    Give varaibles sensible names.

    Deal with the possiblity of:

            for(i=0; i<n; i++){
                scanf("%llu", &x);
                v1.push_back(x);
                v2.push_back(0);
            }
    

    n being zero here.

    Your code does enough pointer and index arithmetic I'd be surprised if it wasn't corrupting the heap by writing out-of-bounds on a vector.