简体   繁体   English

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

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

Given an array of strings, I am writing a class to separated them into different groups according to their length, ie the ones of same length goes to the same group. 给定一个字符串数组,我正在编写一个类,根据它们的长度将它们分成不同的组,即,相同长度的将进入同一组。 The number of groups and the size of each group are unknown. 组的数量和每个组的大小是未知的。

My idea is following: I use a private data member std::vector<std::vector<std::int> > m_groups , with the intention that the outer vector maintains the groups, and the inner vector tracks all the indices of strings belong to one group. 我的想法如下:我使用私有数据成员std::vector<std::vector<std::int> > m_groups ,目的是外部向量维护组,内部向量跟踪字符串的所有索引属于一组

The problem is, once I push strings into the vector, some of my data members are corrupted. 问题是,一旦将字符串推入向量中,我的某些数据成员就会损坏。 Could anyone please have a look? 有人可以看看吗?

Here is the simplified code: 这是简化的代码:

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;
};

in the constructor: A::print_cst2() { for (int c = 0; c < m_Ncst; c++) { printf("%d ", m_cst2[4*c]); 在构造函数中: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 + 1]); printf("%d ", m_cst2[4*c+2]); printf(“%d”,m_cst2 [4 * c + 2]); printf("%d ", m_cst2[4*c+3]); 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]]);
    }

    ...
}

...

I compiled the code and run. 我编译了代码并运行。 The data in the end of array m_cst2 gets corrupted. 数组m_cst2末尾的数据已损坏。 This seems connected to the use of std::vector . 这似乎与std::vector的使用有关。 User comingstorm provided an interesting clue : the outer std::vector stores an array of fixed-size std::vector<int> datastructures in its heap allocation. 用户comingstorm提供了一个有趣的线索外部std::vector在其堆分配中存储了固定大小的std::vector<int>结构数组。 Is that the answer? 那是答案吗? Not sure though. 虽然不确定。 So, post this and ask for suggestions. 因此,发布此并征求建议。

PS: if you have a better idea to do this task, please do tell me ... if you need more information, please post. PS:如果您有更好的主意来执行此任务,请告诉我...如果您需要更多信息,请发表。

I appreciate your time. 感谢您的宝贵时间。

Some improvements below. 以下是一些改进。 In particular you had an off by 1 index error and the incrementation of k was incorrect: 特别是您的索引偏离了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++;
    }

    ...
}

If the code you posted is the actual code you're using, then this will corrupt memory. 如果您发布的代码是您正在使用的实际代码,那么这将损坏内存。

Assume n is 4. 假设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
}

There is no need to go further. 无需进一步。 The value of n is 4, and clearly you are going to go out-of-bounds in m_cst2 when you write to m_cst2[1], m_cst2[2] , etc. as the only valid entry is m_cst2[0] . n 4,并明确你要出门的越界在m_cst2当你写m_cst2[1], m_cst2[2]等作为唯一有效的入口是m_cst2[0]

So your memory corruption probably has nothing to do with std::vector (it is very difficult to mess up a vector of objects), and it more than likely has to do with the code above. 因此,您的内存损坏可能与std::vector没有关系(很难弄乱对象的向量),并且与上面的代码很有可能有关。

Also, you should use std::vector instead of new[]/delete[] in your code. 另外,您应该在代码中使用std::vector而不是new[]/delete[] If you're going to use vector for one thing, why not take advantage of it wherever and whenever you can? 如果您打算将vector用于一件事,何不在任何时间和地点尽可能利用它?

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

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