c++ cout给出带解引用指针的unexpected



所以,我有一个函数,它返回一个指针到动态分配的双精度体,我需要打印它指向的值(我知道很傻)。

double * ans1p = dot(v1, v2);
    double ans1 = *ans1p;
    cout << "Answer to problem 1:" << endl;
    cout << ans1 << endl;
    cout << *ans1p << endl;

第一个cout语句返回期望的值。

第二个返回随机和意外的东西。有什么区别?在这两种情况下,输出的似乎都是ans1p所指向的值。

我宁愿完全消除ans1和它的cout语句。

好的,这是点函数:

double * dot(Vector &v1, Vector &v2) {
if (getLength(v1) != getLength(v2) ) {
    std::cout << "Error: cannot perform dot product. Vectors must be " <<
        "equal length." << std::endl;
    return 0;
}
double result = 0;
for (unsigned int i = 1; i <= getLength(v1); ++i) {
    result += (v1.elements[i] * v2.elements[i]);
}
double * resultPtr = new double;
resultPtr = &result;
return resultPtr;
}

郑重声明,我不会尝试这样做,但这是作业的一部分。我应该在大小不匹配的情况下返回0指针。

好的,看着它,我可以看到,结果是超出范围的函数返回时,我返回的指针只是指向那里(对吗?)。但是,我想不出如何去做我想做的事。

我想我可以在函数外部声明一个双指针,将指针作为参数传递,并在函数内部设置它。但我想弄清楚如何按照我计划的方式去做。不过,想想看,也许这样做更好一旦我明白了旧方法是怎么回事,对吧?

你的问题就在这里:

double * resultPtr = new double;
resultPtr = &result;
return resultPtr;

你在堆上分配一个新的double…然后将一个局部变量的地址赋给resultPtr。您将获得内存泄漏(使用new double分配的内存丢失),然后返回所述局部变量的地址。这是未定义行为。这意味着任何事情都有可能发生。

要解决这个问题,必须更改赋值,使实际使用刚才分配的内存:

double * resultPtr = new double;
*resultPtr = result; // assign the value to the value pointed to resultPtr
return resultPtr;

或者更好:

return new double(result);

考虑到OP使用指针,那么这是无关紧要的。

或者您也可以放弃整个内存分配并返回resultdouble是相当轻的,我真的不明白为什么你绝对必须返回一个指针,而不是值本身:

double dot(Vector &v1, Vector &v2) {
    // check here and throw an exception if needed instead of returning 0
    double result = 0.0;
    for (unsigned int i = 1; i <= getLength(v1); ++i) {
        result += (v1.elements[i] * v2.elements[i]);
    }
    return result; // return the value
}

最新更新