- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我试图解决 SPOJ ( http://www.spoj.com/problems/GSS1) 上的一个问题,并最终使用线段树编写了以下代码。代码工作得很好。但是在某些输入上,它给出了一个段错误,特别是在程序结束时,当它试图从堆栈中释放 vector 的内存时。我已经花了很多时间,但找不到任何错误。任何帮助将不胜感激。
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
struct Node{
int bend;
int bsum;
int ebeg;
int esum;
int maxSum;
Node(): bend(0), bsum(0), ebeg(0), esum(0), maxSum(0){}
Node(const Node& other): bend(other.bend), bsum(other.bsum), ebeg(other.ebeg), esum(other.esum), maxSum(other.maxSum){}
~Node(){}
};
class SegmentTree{
int N;
vector<Node> M;
vector<int> A;
public:
SegmentTree(int N){
this -> N = N;
Node temp;
M.resize((1 << ((int)log(N)+2))+1, temp);
}
SegmentTree(const SegmentTree& other): N(other.N), M(other.M), A(other.A) {}
~SegmentTree(){
M.clear();
A.clear();
}
void put(int a){
A.push_back(a);
}
void initialize(int node, int b, int e)
{
if (b == e){
M[node].bsum = M[node].esum = A[b];
M[node].bend = M[node].ebeg = b;
if (A[b] > 0) M[node].maxSum = A[b];
else M[node].maxSum = 0;
}
else
{
//compute the values in the left and right subtrees
int boundary = (b+e)/2;
initialize(2 * node, b, boundary);
initialize(2 * node + 1, boundary + 1, e);
//maxSum
M[node].maxSum = max( M[2*node].esum+M[2*node+1].bsum, max(M[2*node].maxSum, M[2*node+1].maxSum));
//bsum
M[node].bsum = M[2*node].bsum;
if(M[2*node].bend == boundary && M[2*node+1].bsum >= 0) M[node].bsum += M[2*node+1].bsum, M[node].bend = M[2*node+1].bend;
else M[node].bend = M[2*node].bend;
//esum
M[node].esum = M[2*node+1].esum;
if(M[2*node+1].ebeg == boundary + 1 && M[2*node].esum >= 0) M[node].esum += M[2*node].esum, M[node].ebeg = M[2*node].ebeg;
else M[node].ebeg = M[2*node+1].ebeg;
}
}
Node query(int node, int b, int e, int i, int j)
{
Node ret;
ret.maxSum = -1;
//if the current interval doesn't intersect
//the query interval return -1
if (i > e || j < b)
return ret;
//if the current interval is included in
//the query interval return M[node]
if (b >= i && e <= j)
return M[node];
//use left and right part of the interval
Node p1, p2;
int boundary = (b+e)/2;
p1 = query(2 * node, b, boundary, i, j);
p2 = query(2 * node + 1, boundary + 1, e, i, j);
if (p1.maxSum == -1)
return p2;
if (p2.maxSum == -1)
return p1;
//maxSum
ret.maxSum = max(p1.esum + p2.bsum, max(p1.maxSum, p2.maxSum));
//bsum
ret.bsum = p1.bsum;
if(p1.bend == boundary && p2.bsum >= 0) ret.bsum += p2.bsum, p1.bend = p2.bend;
else ret.bend = p1.bend;
//esum
ret.esum = p2.esum;
if(p2.ebeg == boundary + 1 && p1.esum >= 0) ret.esum += p1.esum, M[node].ebeg = p1.ebeg;
else ret.ebeg = p2.ebeg;
return ret;
}
};
int main(){
int N;
cin >> N;
SegmentTree tree(N);
for (int i = 0; i < N; i++){
int a;
cin >> a;
tree.put(a);
}
tree.initialize(1, 0, N-1);
int M;
cin >> M;
while(M--){
int x, y;
cin >> x >> y;
Node ans;
ans = tree.query(1, 0, N-1, x-1, y-1);
cout << ans.maxSum << endl;
}
}
例如,在输入时:
9
-2 1 -3 4 -1 2 1 -5 4
1
1 9
程序在程序末尾给出段错误。回溯如下:
(gdb) backtrace
#0 0x4e584494 in malloc_consolidate () from /lib/libc.so.6
#1 0x4e584f1d in _int_free () from /lib/libc.so.6
#2 0x4eb54500 in operator delete(void*) () from /lib/libstdc++.so.6
#3 0x0804a581 in __gnu_cxx::new_allocator<int>::deallocate (this=0xbfffee68, __p=0x804f1c0) at /usr/lib/gcc/i686-redhat-linux/4.7.2/../../../../inclu
de/c++/4.7.2/ext/new_allocator.h:100
#4 0x08049e21 in std::_Vector_base<int, std::allocator<int> >::_M_deallocate (this=0xbfffee68, __p=0x804f1c0, __n=16) at /usr/lib/gcc/i686-redhat-lin
ux/4.7.2/../../../../include/c++/4.7.2/bits/stl_vector.h:175
#5 0x080498ff in std::_Vector_base<int, std::allocator<int> >::~_Vector_base (this=0xbfffee68, __in_chrg=<optimized out>) at /usr/lib/gcc/i686-redhat
-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_vector.h:161
#6 0x08049628 in std::vector<int, std::allocator<int> >::~vector (this=0xbfffee68, __in_chrg=<optimized out>) at /usr/lib/gcc/i686-redhat-linux/4.7.2
/../../../../include/c++/4.7.2/bits/stl_vector.h:404
#7 0x08048dcb in SegmentTree::~SegmentTree (this=0xbfffee58, __in_chrg=<optimized out>) at test.cpp:35
#8 0x08048b7b in main () at test.cpp:134
如您所见,错误发生在调用 ~SegmentTree() 时。控件甚至没有转移到 M.clear() (理想情况下应该取消分配内存)并导致段错误。那么,这个段错误的原因是什么?
感谢您的帮助!
最佳答案
最可能的原因是您的程序某处出现了内存损坏。如果我不得不猜测,我会说您可能对 M[]
进行了越界写入。
尝试在 valgrind
下运行程序.
关于c++ - std::vector 析构函数中的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18551601/
我开始考虑在我 future 的项目或重构中实现控制反转容器,我想知道在正确设计依赖项时哪些原则(除了 GoF 模式)可能需要牢记在心。假设我需要构建一个简单的控制台应用程序,如果它可以访问互联网,它
假设我有一个 RxC contingency table 。这意味着有 R 行和 C 列。我想要一个维度为 RC × (R + C − 2) 的矩阵 X,其中包含行的 R − 1 “主效应”以及列的
我正在尝试使用 DKMS 为正在运行的内核 (4.4) 构 build 备树覆盖。我天真的 Makefile 如下: PWD := $(shell pwd) dtbo-y += my-awsome-o
我有一个 sencha touch 项目。我是用 phonegap 2.9 构建的,并且可以正常工作 device.uuid 返回到设备 ID。当我尝试使用 3.1 device.uuid 构建时抛出
我在安装了 Xcode 4.5.1 的 Mt Lion 上运行。 默认情况下,当我构建并部署到 iOS 5.1 设备时,显示会在我旋转设备时旋转,但当我部署到 iOS 6 模拟器或运行 iOS 的 i
我正在尝试使用 Google Analytics Reporting API v4 构建多折线图。 一张图表,其中我按每天的 session 计数为每个设备(台式机/平板电脑/移动设备)设置了一条线。
我一生都无法使用 xcode 组织者“自动设备配置”中的“团队配置配置文件”在 xcode 4.0.1 中将我的应用程序构建到我的 iPad 上。 该应用程序完美地构建到模拟器,但当我构建到 iPad
我是一名优秀的程序员,十分优秀!