繁体   English   中英

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

[英]memory corrupted using std::vector in constructor

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

我的想法如下:我使用私有数据成员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 <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的使用有关。 用户comingstorm提供了一个有趣的线索外部std::vector在其堆分配中存储了固定大小的std::vector<int>结构数组。 那是答案吗? 虽然不确定。 因此,发布此并征求建议。

PS:如果您有更好的主意来执行此任务,请告诉我...如果您需要更多信息,请发表。

感谢您的宝贵时间。

以下是一些改进。 特别是您的索引偏离了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++;
    }

    ...
}

如果您发布的代码是您正在使用的实际代码,那么这将损坏内存。

假设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]等作为唯一有效的入口是m_cst2[0]

因此,您的内存损坏可能与std::vector没有关系(很难弄乱对象的向量),并且与上面的代码很有可能有关。

另外,您应该在代码中使用std::vector而不是new[]/delete[] 如果您打算将vector用于一件事,何不在任何时间和地点尽可能利用它?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM