使用全局声明的向量时 C++ 中的双重错误/损坏
Double free error/ corruption in C++ while using globally declared vectors
对于此代码,
#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;
}
我得到了我想要的输出,但是在主函数执行后 '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
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)
以获得异常而不是内存损坏。
声明变量尽可能接近它们的初始化,并尽快让它们脱离范围,以减少变量的长度并减少 "state" 程序的数量。
给变量起一个合理的名字。
处理以下可能性:
for(i=0; i<n; i++){
scanf("%llu", &x);
v1.push_back(x);
v2.push_back(0);
}
n
此处为零。
您的代码执行了足够多的指针和索引运算,如果它没有通过在向量上越界写入来破坏堆,我会感到惊讶。
对于此代码,
#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;
}
我得到了我想要的输出,但是在主函数执行后 '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
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)
以获得异常而不是内存损坏。
声明变量尽可能接近它们的初始化,并尽快让它们脱离范围,以减少变量的长度并减少 "state" 程序的数量。
给变量起一个合理的名字。
处理以下可能性:
for(i=0; i<n; i++){
scanf("%llu", &x);
v1.push_back(x);
v2.push_back(0);
}
n
此处为零。
您的代码执行了足够多的指针和索引运算,如果它没有通过在向量上越界写入来破坏堆,我会感到惊讶。