簡體   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