【问题标题】:Double free error/ corruption in C++ while using globally declared vectors使用全局声明的向量时 C++ 中的双重免费错误/损坏
【发布时间】:2019-03-26 16:22:53
【问题描述】:

对于这段代码,

#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;
    }

我得到了我想要的输出,但是在 main 执行 'return 0' 之后,我得到了这个错误

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

我使用另一个代码得到了答案,但我想了解为什么此代码会出现此错误。

我认为 SpreadTheWord() 没有任何问题,但以防万一你想看看 SpreadTheWord() 做了什么

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;
}

谢谢!

编辑:对不起,我忘了附上输入

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 

问题来自这里:https://www.codechef.com/SNCKQL19/problems/SPREAD2

【问题讨论】:

  • 请提供输入
  • 设置初始值而不等待输入可能更容易。我输入“0\n”并没有复制。
  • 输入2 2 2 2,您可以在此处访问超出范围的向量:v2[j] = 1。编译一个调试版本,调试版本通常会检查向量元素是否使用超出范围的索引进行访问。
  • 我现在在问题中添加了一个输入。您可以查看链接(问题中提供)以获取其他输入。谢谢!

标签: c++ stl global-variables stdvector double-free


【解决方案1】:
            while(v2[m] != 0){
                v2[m] = 2;
                m++;
            }
    if(k!=0 && v2[i] == 2){ //condition 2
        v2[j] = 1;
        k--;
        j++;
    }

证明v2[j]v2[m] 始终在v2 的范围内并非易事。

一般来说,SpreadTheWord 是一堆意大利面条逻辑,可能正在破坏堆。


[x] 替换为.at(x) 以获得异常而不是内存损坏。

声明变量尽可能接近它们的初始化,并让它们尽快超出范围,以减少变量挂起的长度并减少“状态”程序的数量。

为变量提供合理的名称。

处理以下可能性:

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

n 在这里为零。

你的代码做了足够多的指针和索引运算,如果它没有通过在向量上写入越界来破坏堆,我会感到惊讶。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多