为什么在 C++ 中使用动态分配的内存时我的编译器会报错
why is it that my compiler gives me error when working with dynamically allocated memory in c++
#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 行。
运算符 []
的 precedence 高于运算符 *
。所以 *left[i]
的意思是 "take index i
from left
and then dereference it." 你实际想要的是 "dereference left
and then take index i
from the result",它会被表示为 (*left)[i]
。
其他向量指针也一样:(*right)[i]
、(*merged)[i]
虽然,实际上,没有理由在这里使用动态分配,并且因为您在没有任何对应的 delete
的情况下调用 new
,所以您正在泄漏内存。在从函数 split
和 count_inv
返回之前,您需要 delete
动态分配的 vector
对象,或者更明智地,只需定义向量 left
、right
和 merged
作为自动(局部)变量,就像你已经对向量 C
.
所做的那样
因此,对于您所看到的特定问题的解释是,您没有使用您认为的运算符取消引用指针:
*left[i]
这采用编译器认为是 vector<long long>
数组的 _i_th 元素,然后尝试用一元 *
取消引用它,这显然是行不通的.您只需像这样将其括起来即可解决此问题:(*left)[i]
.
但是,您的代码存在更深层次的问题。使用 new
在堆上分配标准容器通常是不了解如何使用 C++ 标准库的人的标志。你说"the code above required some dynamic memory allocation",但这很可能不是真的!
看看这个:
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;
}
而且它也能正常工作。您可能需要多花一点时间了解使用标准容器的最佳方式。
正如其他人指出的那样,基本的句法问题是您对 *symbol[i]
的解释方式的假设是不正确的。无论您在哪里编码,打印出运算符优先级 table 和 post 都可能会很好(就像我多年来所做的那样)。
这是给你的:http://en.cppreference.com/w/cpp/language/operator_precedence
#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 行。
运算符 []
的 precedence 高于运算符 *
。所以 *left[i]
的意思是 "take index i
from left
and then dereference it." 你实际想要的是 "dereference left
and then take index i
from the result",它会被表示为 (*left)[i]
。
其他向量指针也一样:(*right)[i]
、(*merged)[i]
虽然,实际上,没有理由在这里使用动态分配,并且因为您在没有任何对应的 delete
的情况下调用 new
,所以您正在泄漏内存。在从函数 split
和 count_inv
返回之前,您需要 delete
动态分配的 vector
对象,或者更明智地,只需定义向量 left
、right
和 merged
作为自动(局部)变量,就像你已经对向量 C
.
因此,对于您所看到的特定问题的解释是,您没有使用您认为的运算符取消引用指针:
*left[i]
这采用编译器认为是 vector<long long>
数组的 _i_th 元素,然后尝试用一元 *
取消引用它,这显然是行不通的.您只需像这样将其括起来即可解决此问题:(*left)[i]
.
但是,您的代码存在更深层次的问题。使用 new
在堆上分配标准容器通常是不了解如何使用 C++ 标准库的人的标志。你说"the code above required some dynamic memory allocation",但这很可能不是真的!
看看这个:
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;
}
而且它也能正常工作。您可能需要多花一点时间了解使用标准容器的最佳方式。
正如其他人指出的那样,基本的句法问题是您对 *symbol[i]
的解释方式的假设是不正确的。无论您在哪里编码,打印出运算符优先级 table 和 post 都可能会很好(就像我多年来所做的那样)。
这是给你的:http://en.cppreference.com/w/cpp/language/operator_precedence