内存在构造函数中使用std :: vector损坏

时间:2015-03-01 15:09:04

标签: c++ memory

给定一个字符串数组,我正在编写一个类,根据它们的长度将它们分成不同的组,即相同长度的组转到同一组。组的数量和每组的大小是未知的。

我的想法是: 我使用私有数据成员std::vector<std::vector<std::int> > m_groups,意图是外部向量维护组,内部向量跟踪属于一个组的字符串的所有索引。

问题是,一旦我将字符串推入向量,我的一些数据成员就会被破坏。有谁可以看看?

以下是简化代码:

class A {

public:
    A(std::string words[], int num, int c1[], int m, int c2[], int n);
    ~A();

    void print_state();

private:

    int *m_var; 
    int m_Nvar;

    std::vector<std::vector<std::int> > m_doms;
    std::vector<std::vector<std::int> > m_groups;
    std::vector<std::string> > m_words;

    int *m_cst1;
    int *m_cst2;
    int m_Ncst;
};

在构造函数中:     A :: print_cst2()     {        for(int c = 0; c&lt; m_Ncst; c ++)        {            printf(“%d”,m_cst2 [4 * c]);            printf(“%d”,m_cst2 [4 * c + 1]);            printf(“%d”,m_cst2 [4 * c + 2]);            printf(“%d”,m_cst2 [4 * c + 3]);        }     }

A::A(std::string words[], int num,
    int c1[], int m, int c2[], int n) {

    ...
    m_cst1 = new int[m/2];
    m_cst2 = new int[n/4];
    m_Ncst = n/4;
    m_Nvar = m/2;

    for (int i = 0; i < n; i+=4)
    {
        m_cst2[i] = c2[i];
        m_cst2[i+1] = c2[i+1];
        m_cst2[i+2] = c2[i+2];
        m_cst2[i+3] = c2[i+3];
    }

    print_cst2();  // (1) we print the m_cst2 
    // we are only interested, the words of length smaller than m_max_len
    // put m_max_len number of empty vectors (groups) in the group vector
    for (int i = 0; i < m_max_len; i++)
    {   
        m_groups.push_back(std::vector<int>());
    }   
    print_cst2();  // (2) we print the m_cst2 again 

    // go through every words and copy words of interest to m_words
    // push the index of the word to the group it belongs to (by its length)
    for (int i = 0, k = 0; i < num; i++, k++)
    {   
        int len = words[i].length();
        if (len > m_max_len)
            continue;
        m_words.push_back(words[i]);
        m_groups[len].push_back(k);
    }

    // you can ignore this part: link the group to another structure
    for (int i = 0; i < m_Nvar; i++)
    {
         m_doms.push_back(m_groups[m_cst1[i]]);
    }

    ...
}

...

我编译了代码并运行。数组m_cst2末尾的数据已损坏。这似乎与std::vector的使用有关。 User comingstorm provided an interesting clue外部std::vector在其堆分配中存储一个固定大小的std::vector<int>数据结构数组。这是答案吗?不过不确定。所以,发布这个并征求建议。

PS:如果您有更好的想法来完成这项任务,请告诉我......如果您需要更多信息,请发布。

我感谢你的时间。

2 个答案:

答案 0 :(得分:1)

以下一些改进。特别是你有一个off by 1索引错误,并且k的增量不正确:

CwordSolver::CwordSolver(std::string words[], int num,
int c1[], int m, int c2[], int n) {

    ...

    // we are only interested, the words of length smaller than m_max_len
    m_groups.resize(0);
    m_groups.resize(m_max_len, std::vector<int>());

    // go through every words and copy words of interest to m_words
    // push the index of the word to the group it belongs to (by its length)
    int k = 0;    // the index in m_words
    for (int i = 0; i < num; i++)
    {   
        int len = words[i].length();
        if (len >= m_max_len)
            continue;
        m_words.push_back(words[i]);
        m_groups[len].push_back(k);
        k++;
    }

    ...
}

答案 1 :(得分:0)

如果您发布的代码是您正在使用的实际代码,则会损坏内存。

假设n是4.

m_cst2 = new int[n/4];  // so you have room for 1 item
m_Ncst = n/4;
m_Nvar = m/2;

for (int i = 0; i < n; i+=4)
{
    m_cst2[i] = c2[i];      // valid
    m_cst2[i+1] = c2[i+1];  // memory overwrite
    m_cst2[i+2] = c2[i+2];  // memory overwrite
    m_cst2[i+3] = c2[i+3];  // memory overwrite
}

没有必要走得更远。 n的值为4,当您写入m_cst2等时,显然您将在m_cst2[1], m_cst2[2]中超出范围,因为唯一有效的条目是{{1} }}

所以你的内存损坏可能与m_cst2[0]无关(很难弄乱对象的向量),而且很可能与上面的代码有关。

此外,您应该在代码中使用std::vector而不是std::vector。如果您将new[]/delete[]用于一件事,为什么不随时随地利用它?