4

我有一个程序从 mysql 数据库中获取一些数据,调用一个函数来处理该数据,然后退出。运行它时出现奇怪的错误...当函数返回值时程序崩溃。正如我怀疑这是我的一个类的析构函数的问题。该类包含两个向量(一个是双精度,另一个是我自己编写的日期类)。当双打向量被破坏时程序崩溃。

手动擦除析构函数中的向量不会做任何事情。

当我手动调用析构函数时,我没有收到此错误。仅当我从函数返回值时才会发生这种情况。逐行崩溃发生在 stl_vector.h 中

{ _M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage - this->_M_impl._M_start); }

谷歌搜索并不是很有帮助......我发现分配一个超出向量大小的值可能会触发这样的事情,但我已经检查了我的代码并确保不会发生这种情况。

错误:

Program received signal SIGTRAP, Trace/breakpoint trap.
In ntdll!DbgUiConnectToDbg () (C:\WINDOWS\system32\ntdll.dll)

调用堆栈:

#0 7C90120F ntdll!DbgUiConnectToDbg() (C:\WINDOWS\system32\ntdll.dll:??)
#1 7C96EE31 ntdll!RtlpNtMakeTemporaryKey() (C:\WINDOWS\system32\ntdll.dll:??)
#2 7C96F26E ntdll!RtlpNtMakeTemporaryKey() (C:\WINDOWS\system32\ntdll.dll:??)
#3 7C970456 ntdll!RtlpNtMakeTemporaryKey() (C:\WINDOWS\system32\ntdll.dll:??)
#4 7C94BAFC ntdll!LdrFindEntryForAddress() (C:\WINDOWS\system32\ntdll.dll:??)
#5 00000000 0x006b0000 in ??() (??:??)
#6 00000000 0x50000061 in ??() (??:??)
#7 00000000 0x00f57008 in ??() (??:??)
#8 00000000 0x006b0000 in ??() (??:??)
#9 00000000 0x00f57008 in ??() (??:??)
#10 00000000    0x40000060 in ??() (??:??)
#11 00000000    0x00f60558 in ??() (??:??)
#12 00000000    0x002240b0 in ??() (??:??)
#13 00000000    0x00223804 in ??() (??:??)
#14 7C96F2D7    ntdll!RtlpNtMakeTemporaryKey() (C:\WINDOWS\system32\ntdll.dll:??)
#15 7C91A1BA    ntdll!RtlpUnWaitCriticalSection() (C:\WINDOWS\system32\ntdll.dll:??)
#16 77C2C2DE    msvcrt!free() (C:\WINDOWS\system32\msvcrt.dll:??)
#17 00000000    0x006b0000 in ??() (??:??)
#18 00000000    0x00000000 in ??() (??:??)

在 Winxp 上的 Code::Blocks 中使用 MinGW。有很多代码,因为我真的不知道哪里出错了,所以我不知道这里应该包括什么......

谢谢您的帮助。

编辑:

一堆可能相关也可能不相关的代码:

获取数据,初始化 dated_observations 对象(其中的向量导致崩溃)并将数据添加到它们(请注意,从此时开始直到函数终止,我只从这些对象中读取值......没有添加任何元素、修改或删除):

query_ss << "SELECT * FROM stock_data WHERE stock_id = " << stock1_id;
mysql_query(connect,query_ss.str().c_str());
query_ss.str("");
res_set = mysql_store_result(connect);
numrows = mysql_num_rows(res_set);

dated_observations s1_p(numrows);
dated_observations s1_r(numrows);

for(i = 0; i < numrows; i++) {
    row = mysql_fetch_row(res_set);
    s1_p.my_insert(row[2], std::atof(row[3]));
    s1_r.my_insert(row[2], std::atof(row[4]));
}

过时的班级:

#ifndef _DATED_H_
#define _DATED_H_

#include <vector>
#include "date.h"       // my date class

template <class T> class dated {
private:
    int counter;
public:
    vector<date> dates_;
    vector<T> elements_;
    //dated<T>();
    dated<T>(const int&);
    dated<T>(const dated<T>&);
    dated<T> operator= (const dated<T>&);
    ~dated() { clear(); };
    void clear();                     // erasing
    void insert(const date&, const T&); // insert somewhere
    void my_insert(const date&, const T&); // insert at the end

    bool empty() const ;
    int  size() const ;
    bool contains(const date& d) const ;
    date date_at(const int& t) const ; // accessing elements, here dates
    T element_at(const int& t) const ;  // index directly
    T element_at(const date& d) const ; // index indirectly, specify what date

    //date last_date() const ;
    //T last_element() const;

    // next: the element either on date d, if d is here, else the last observation before d.
    T current_element_at(const date& d) const ;

    vector<T> elements() const; // all elements as vector<T>
    vector<date> dates() const;  // all dates as vector<date>

    date first_date() const;  // simple queries
    date last_date() const;
    T first_element() const;
    T last_element() const;

    void set_counter(int cnt);
    int get_counter() const;

    int index_of_date(const date& d) const; // when searching in the data,
    int index_of_last_date_before(const date& d) const; // these are useful functions
    int index_of_first_date_after(const date& d) const;

    int no_observations_between(const date&first, const date& last) const;

    void remove(const date&);         // removing one or more elements
    void remove_between_including_end_points(const date&, const date&);
    void remove_between(const date&, const date&);
    void remove_before(const date&);
    void remove_after(const date&);
};

#include "dated_main.h"
#include "dated_search.h"
#include "dated_remove.h"

template<class T> dated<T> observations_between(const dated<T>& obs,const date&first, const date& last);
template<class T> dated<T> observations_after(const dated<T>& obs, const date& first);
template<class T> dated<T> observations_before(const dated<T>& obs, const date& last);
template<class T> dated<T> end_of_year_observations(const dated<T>&);
template<class T> dated<T> beginning_of_month_observations(const dated<T>&);
template<class T> dated<T> end_of_month_observations(const dated<T>&);
template<class T> dated<T> observations_matching_dates(const dated<T>& obs, const vector<date>& dates);

#include "dated_util.h"
#endif

过时类的一些方法:

//template<class T> dated<T>::dated(){;};   // not necessary to do anything,

template<class T>dated<T>::dated(const int& init_size = 0) {
    // for speed, initialize first with correct size and then copy
    counter = 0;
    if(init_size > 0) {
        dates_=vector<date>(init_size);
        elements_=vector<T>(init_size);
    }
};

template<class T>dated<T>::dated(const dated<T>& dobs) {
    // for speed, initialize first with correct size and then copy
    counter = 0;
    dates_=vector<date>(dobs.size());
    elements_=vector<T>(dobs.size());
    for (int t=0;t<dobs.size();++t){
        dates_[t]      = dobs.date_at(t);
        elements_[t]   = dobs.element_at(t);
    };
};

template<class T> dated<T> dated<T>::operator= (const dated<T>& dobs) {
    counter = 0;
    if (this==&dobs) return *this; // check against self assignment;
    clear();
    dates_=vector<date>(dobs.size());
    elements_=vector<T>(dobs.size());
    for (int t=0;t<dobs.size();++t){
        dates_[t]        = dobs.date_at(t);
        elements_[t]     = dobs.element_at(t);
    };
    return *this;
};

template<class T> dated<T>::~dated();

template<class T> bool dated<T>::empty() const { return (dates_.size()<1); };

template<class T> int  dated<T>::size() const { return dates_.size(); };

template<class T> date dated<T>::date_at(const int& t) const { // accessing with bounds checking
   if ( (t>=0) && (t<size()) ) return dates_[t];
   return date();
};

template<class T> T dated<T>::element_at(const int& t) const {  // accessing with bounds checking
   if ( (t>=0) && (t<size()) ) return elements_[t];
   return T();
};

template<class T> void dated<T>::set_counter(int cntr){
    counter = cntr;
}

template<class T> int dated<T>::get_counter() const {
    return counter;
}

template<class T> T dated<T>::element_at(const date& d) const {
   if (!contains(d)) return T();
   return elements_[index_of_date(d)];
};

template <class T> void dated<T>::my_insert(const date& d, const T& obs) {
    if (!d.valid()) return;
    elements_[counter] = obs;
    dates_[counter] = d;
    counter++;
};

template<class T> void dated<T>::clear() {
   dates_    .erase(dates_    .begin(),dates_    .end());
   elements_ .erase(elements_ .begin(),elements_ .end());
};

dated_observations 类:

#ifndef _DATED_OBS_H_
#define _DATED_OBS_H_

#include "dated.h"      // templated dated<> class
#include <string>     // ANSI string class

class dated_observations : public dated<double>{
   private:
      string         title_;
   public:
      dated_observations(const dated_observations& dobs); //copy constructor
      dated_observations(const int& init_size = 0) : dated<double>(init_size) {;}

      void clear();
      ~dated_observations() { clear(); };

      void set_title(string s); // title
      string title() const;

      int no_obs() const;
      int no_obs_between(const date& d1, const date& d2) const;
      int no_obs_before(const date& d) const;
      int no_obs_after(const date& d) const;
};

///// io
ostream& operator << (ostream&, const dated_observations& );
void print_dated_observations(ostream& of, const dated_observations& d, int precision=3);

//// mischellaneous utilities
double max_obs(dated_observations& dobs);
double min_obs(dated_observations& dobs);
bool dates_match(const dated_observations& obs1, const dated_observations& obs2);

///// picking subsets.
dated_observations observations_between(const dated_observations& obs,const date& first,const date& last);
dated_observations observations_after(const dated_observations& obs, const date& first);
dated_observations observations_before(const dated_observations& obs, const date& last);
dated_observations observations_matching_dates(const dated_observations& obs, const vector<date>& dates);

///// picking periodic elements
dated_observations beginning_of_month_observations(const dated_observations&);
dated_observations end_of_month_observations(const dated_observations&);
dated_observations end_of_year_observations(const dated_observations&);
dated_observations end_of_year_current_observations(const dated_observations&);

#endif

一些 dated_observations 方法:

dated_observations::dated_observations(const dated_observations& dobs) {
    elements_ = dobs.elements_;
    dates_ = dobs.dates_;
    set_counter(dobs.get_counter());
}

void dated_observations::set_title(string s) { title_ = s; };

void dated_observations::clear() {
   title_ = string();
   dated<double>::clear();
   set_counter(0);
};

另一个编辑:

删除 s1_p & s1_r 初始化和结束之间的所有代码实际上消除了错误。可能试图读取或复制超出向量大小的值会导致这种情况吗?

4

0 回答 0