动态内存分配具有不希望的输出

时间:2014-06-16 17:13:33

标签: c++

所以我上周开始学习C ++,当然,我想熟悉整个指针和面向对象的业务等等。

为此,我为一些基本矩阵计算编写了一个非常简单的程序:

# include <iostream>
using std::cout;
using std::cin;

class Matrix {
        int columns; // x
        int rows; // y
        double* matrix;
    public:
        Matrix (int*);
        void printMatrix();
        void free() {
            delete[] matrix;
            return;
            };
};

Matrix::Matrix(int* dim){
    rows = *dim;
    columns = *(dim + 1);
    matrix = new double [columns*rows];
}

void Matrix::printMatrix(){ 
    int i, j;
    for(i = 0; i < columns; i++){
        for(j=0; j < rows; j++){
            cout << matrix[columns*i + j] << " ";
        }
        cout << "\n";
    }
    return;         
}


int* getMatrix ();

int main () {
    Matrix matrix (getMatrix());
    matrix.printMatrix();
    matrix.free();
    return 0;
}

int* getMatrix (){
    int* dim = new int [2];
    cout << "(m x n)-Matrix, m? ";
    cin >> dim[0];
    cout << "n? ";
    cin >> dim[1];
    return dim;
}

当我选择(4,2)矩阵时,会出现问题(如我所见)。据我从各种教程中了解,

matrix = new double [columns*rows];

应该分配这么多内存:列*行 sizeof(double)。此外,每个小区&#39;应使用 0 初始化。

但是,选择一个(4,2)矩阵,得到函数printMatrix()的以下输出:

0 0 
0 0 
0 6.6727e-319 
0 0 

为什么(3,2)条目未使用 0 初始化?

谢谢!

2 个答案:

答案 0 :(得分:3)

  

此外,每个小组&#39;应该用0初始化。

不。当您编写new double[N]时,该语言不适合您。

  

为什么(3,2)条目没有用0初始化?

如果,你会写new double[N]()而不是!

  

[C++11: 5.3.4/15]:创建类型为T的对象的 new-expression 按如下方式初始化该对象:

     
      
  • 如果省略 new-initializer ,则对象为 default-initialized (8.5);如果没有执行初始化,则该对象具有不确定的值。
  •   
  • 否则, new-initializer 将根据8.5的 direct-initialization 的初始化规则进行解释。
  •   

当然,这有点含糊不清,因为它似乎在讨论new的非数组版本,但实际上它意味着两者; Tdouble[4]

事实上,我们可以看到相同的措辞部分谈论&#34;对象&#34;在数组和非数组的情况下,设置完美的先例:

  

[C++11: 5.3.4/1]: [..] 如果实体是非数组对象, new-expression 将返回指向所创建对象的指针。如果是数组,则为new-expression   返回指向数组初始元素的指针。

现在,证明这条规则基本上是不可能的,因为即使这些值实际上是不确定的,你也可能发现不幸并获得全零,但下面的代码完全无法令人信服一个好的开始:

#include <iostream>
#include <vector>

int main() {
    const std::size_t n = 4;

    {
        std::vector<double> hack;
        hack.push_back(5);
        hack.push_back(6);
        hack.push_back(7);
        hack.push_back(8);
        hack.push_back(9);
        hack.push_back(10);
        hack.push_back(11);
        hack.push_back(12);
    }

    double* a = new double [n];
    double* b = new double [n]();

    for (std::size_t i = 0; i < n; i++)
        std::cout << a[i] << '/' << b[i] << ' ';
    std::cout << '\n';

    delete[] a;
    delete[] b;
}

我设法从中获得0/0 6/0 7/0 8/0,这要归功于一些堆乱,但它仍然只是纯粹的机会,并没有真正展示任何东西(live demo)。 / p>

不幸的是,new double[4](316)无效(根据(),在直接初始化期间,[C++11: 8.5/16]内的值被明确禁止用于数组)所以我们不能建议new double[4](0)是可靠的,并使用316的示例来说服你。

答案 1 :(得分:2)

在C ++中,只有静态变量初始化为0  自动和动态变量应由您初始化。