初始化影响与该初始化无关的代码

时间:2018-09-01 07:00:07

标签: c++ c++11 pointers

在下面的代码中,我认为最后一个循环将打印1 2 3 4四次,每一行新出现一次。该代码打印1 3 2 1而不是1 2 3 4四次。

  • 如果我将{1, 3, 2, 1}的类型从double更改为int,问题就解决了。
  • 如果我将double line[] = {1, 3, 2, 1}从if-else块中取出,问题将消失。

我只是不了解变量double line[]的初始化如何影响vector <double *> v的分配。

#include <iostream>
#include <cmath>
#include <vector>

int main()
{
    std::vector <double*> v;
    for(int i = 0; i < 4; i++)
    {
        double line[] = {1, 2, 3, 4};
        v.push_back(new double[4]);
        v[std::abs(v.size()) - 1] = line;
    }
    if(0 > 1)
    {

    }
    else
    {
        double line[] = {1, 3, 2, 1};
    }
    for(int i = 0; i < 4; i++)
    {
        for(int j = 0; j < 4; j++)
        {
            std::cout << v[i][j] << ' ';
        }
        std::cout << '\n';
    }
}

1 个答案:

答案 0 :(得分:1)

这里

 for(int i = 0; i < 4; i++)
    {
        double line[] = {1, 2, 3, 4};      
        v.push_back(new double[4]);
        v[std::abs(v.size()) - 1] = line;
    }

您所拥有的只是内存泄漏+未定义的行为。

您正在堆栈中创建line,作为每个迭代器的末尾,它超出了范围,这意味着您未按预期进行。访问后,它们会给您UB。 其次,每次new double[4]都在堆中创建,您没有对其进行管理/释放,这会导致内存泄漏!

您可能想这样做:

#include <vector>
#include <array>

std::vector <std::array<int, 4>> v;

for (int i = 0; i < 4; i++) v.emplace_back(std::array<int, 4>{ 1, 2, 3, 4 });

将给出一个4x4维数组(二维)的向量。 并使用基于范围的循环对其进行访问:

for (const std::array<int, 4>& row : v)
{
    for (const int element : row) std::cout << element << " ";
    std::cout << std::endl;
}

但是,看起来您正在执行分配,您必须在其中进行std::vector <int*> v;处理。如果是这样,则需要额外的取消分配以释放使用new关键字创建的内存。

std::vector <int*> v;

for (int i = 0; i < 4; i++) 
    v.emplace_back(new int[4]{ 1, 2, 3, 4 }); // create and store to vector

for (const int* row : v)
    for (int j = 0; j < 4; j++)
    // do print

for (int i = 0; i < 4; i++)  delete[] v[i];   // free the memory using delete

但是,我建议您使用smart pointers,因为您倾向于使用C ++而不是C。 例如,可以使用std::unique_ptr

编写上述代码
std::vector <std::unique_ptr<int[]>> v;

for (int i = 0; i < 4; i++)
    v.emplace_back(std::unique_ptr<int[]>(new int[4]{ 1, 2, 3, 4 }));

for (const std::unique_ptr<int[]>& row : v)
    for (int j = 0; j < 4; j++)
        std::cout << row[j] << " ";
 // no mannual memory management is required.