C++ cout 给出意外的解引用指针

发布于 2024-12-14 02:14:10 字数 1091 浏览 0 评论 0原文

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

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 指针。

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

我想我可以在函数外部声明一个双指针,将指针作为参数传递,然后将其设置在函数内部。但我有点想弄清楚如何按照我计划的方式去做。不过,想一想,当我了解了旧方式的情况后,这样做可能会更好,对吗?

So, I have a function which returns a pointer to a dynamically allocated double, and I need to print the value to which it points (silly I know).

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

The first cout statement returns the expected value.

The second returns something random and unexpected. What's the difference? It seems to be that in both cases what's being printed is the value pointed to by ans1p.

I'd rather eliminate ans1 and its cout statement entirely.

OK, here is the dot function:

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

For the record, I wouldn't attempt to do it this way, but it's part of an assignment. And I'm supposed to return the 0 pointer in the event of mismatched sizes.

OK, looking at it, I can see that result is out of scope when the function returns, and the pointer I'm returning just points there (right?). But then, I can't think of how to do what I want to do.

I suppose I could declare a double pointer outside the function, pass the pointer as an argument, and set it inside the function. But I'd kind of like to figure out how to do it the way I planned. Although, thinking about it, it might be better to do it this way once I understand what's going on with the old way, right?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

拥抱我好吗 2024-12-21 02:14:10

你的问题就在那里:

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必须使用指针,然后这是无关紧要的。留下作为奖励(因为无论如何我都写了这个,删除它会是一种浪费)。

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

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
}

There's your problem right there:

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

You allocate a new double on the heap... then assign the address of a local variable to resultPtr. You get a memory leak (what was allocated with new double is lost), and you then return the address of said local variable. That's undefined behavior. Which means anything can happen.

To fix this, you must change the assignment to actually use the memory you just allocated:

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

Or, better yet:

return new double(result);

Considering the OP has to use a pointer, then this is irrelevant. Left as a bonus (and because I wrote this anyway, deleting it would be a waste).

Or you could also drop the whole memory allocation and return result. doubles are pretty light, and I really don't see why you absolutely must return a pointer rather than the value itself:

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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文