为啥我的编译器在 c++ 中使用动态分配的内存时给我错误

Posted

技术标签:

【中文标题】为啥我的编译器在 c++ 中使用动态分配的内存时给我错误【英文标题】:why is it that my compiler gives me error when working with dynamically allocated memory in c++为什么我的编译器在 c++ 中使用动态分配的内存时给我错误 【发布时间】:2017-05-23 04:55:22 【问题描述】:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <climits>

using namespace std;

vector<long long> count_inv(vector<long long> &left, vector<long long> &right, int &count);

vector<long long> split(vector<long long> &A, int &count)

    if (A.size() == 1)
        return A;
    else
    
        int mid = A.size() / 2;
        int umid = A.size() - mid;
        vector<long long> *left, *right;
        left = new vector<long long>(mid);
        right = new vector<long long>(umid);
        for (int i = 0;i < mid;i++)
            *left[i] = A[i];
        for (int i = mid, j = 0;i < A.size();i++, j++)
            *right[j] = A[i];
        split(*left, count);
        split(*right, count);
        left->push_back(LLONG_MAX);
        right->push_back(LLONG_MAX);
        vector<long long> C = count_inv(*left, *right, count);
        return C;
    


vector<long long> count_inv(vector<long long> &left, vector<long long> &right, int &count)

    vector<long long> *merged;
    merged = new vector<long long>(left.size() + right.size() - 2);
    int i = 0, j = 0, k = 0;
    while (i + j != left.size() + right.size() - 2)
    
        if (left[i] < right[j])
        
            *merged[k] = left[i];
            i++;k++;
        
        else if (left[i] > right[j])
        
            *merged[k] = right[j];
            j++;k++;count++;
        
        else
        
            *merged[k] = left[i];
            *merged[k + 1] = right[j];
            i++;j++;k += 2;
        
    
    return *merged;


int main()

    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int t;
    cin >> t;
    while (t--)
    
        cout << endl;
        int n;
        cin >> n;
        vector<long long> A(n);
        for (int i = 0;i < n;i++)
            cin >> A[i];
        int count = 0;
        vector<long long> S = split(A, count);
        cout << count << endl;
    

    return 0;

上面的代码需要一些动态内存分配,所以我用 c++ 中的新键这样做了,但是编译器给了我以下错误

Severity    Code    Description Project File    Line    Suppression State
Error (active)  E0349   no operator "*" matches these operands  

在我使用“*”的所有行中,我都使用“*”来尊重动态分配的内存,即第 23、25、44、49、54、55 行。

【问题讨论】:

简单地说vector不是一个对象,而是数组操作的接口。 您通常不需要new vector。在这个程序中你当然不需要它。重写为直接使用std::vector,无需任何指针。 【参考方案1】:

运算符[] 的precedence 高于运算符*。所以*left[i] 的意思是“从left 获取索引i,然后取消引用它。”你真正想要的是“取消引用left,然后从结果中获取索引i”,这将表示为(*left)[i]

其他向量指针也一样:(*right)[i](*merged)[i]

虽然,实际上,这里没有理由使用动态分配,并且因为您调用new 没有任何对应的deletes,所以您正在泄漏内存。在从函数splitcount_inv 返回之前,您需要delete 动态分配的vector 对象,或者更明智地,只需将向量leftrightmerged 定义为自动(本地)变量,就像你已经为矢量 C 所做的那样。

【讨论】:

【参考方案2】:

因此,您所看到的具体问题的解释是您没有使用您认为自己的运算符取消引用指针:

*left[i]

这需要编译器认为是vector&lt;long long&gt; 数组的第_i_ 个元素,然后尝试用一元* 取消引用它,这显然是行不通的。您可以通过像这样将其括起来来解决此问题:(*left)[i]

但是,您的代码存在更深层次的问题。使用new 在堆上分配标准容器通常表明有人不了解如何使用 C++ 标准库。你说“上面的代码需要一些动态内存分配”,但这可能不是真的!

看看这个:

vector<long long> count_inv(vector<long long> &left, vector<long long> &right, int &count)

    vector<long long> *merged;
    // snip
    merged = new vector<long long>(left.size() + right.size() - 2);
    return *merged;

抛开这会泄漏内存的事实,你可以这样做:

vector<long long> count_inv(vector<long long> &left, vector<long long> &right, int &count)

    vector<long long> merged(left.size() + right.size() - 2);
    // snip
    return merged;

它也可以正常工作。您或许可以多花一点时间了解使用标准容器的最佳方式。

【讨论】:

我没有什么好的建议,但是那里有很多编码论坛,人们对此主题有很多意见。如果您还不是其中的成员,那也可能值得这样做。【参考方案3】:

正如其他人所指出的,基本的句法问题是您对如何解释 *symbol[i] 的假设是不正确的。无论您在哪里编码,打印出运算符优先级表并将其发布在视线范围内可能会做得很好(就像我多年来所做的那样)。

这是给你的:http://en.cppreference.com/w/cpp/language/operator_precedence

【讨论】:

以上是关于为啥我的编译器在 c++ 中使用动态分配的内存时给我错误的主要内容,如果未能解决你的问题,请参考以下文章

优化动态分配内存的变量

c++基础——动态内存

C++ 删除不会释放所有内存 (Windows)

C++ 动态内存分配(6种情况,好几个例子)

在C语言进行编程中,为啥要释放旧内存?

C++ new的时候,为啥会存在内存分配会失败的情况?啥导致的呢?