我写过以下递归多项式乘法,但它给了我错误,代码在这里
#include<iostream>
#include<vector>
using namespace std;
#define N 4
float *mult(float p[],float q[],int n)
{
float pl[N/2],ql[N/2],ph[N/2],qh[N/2];
float t1[N/2],t2[N/2];
float r[2*N-2],rl[N],rm[N],rh[N];
int i,N2;
if(N==1)
{
r[0]=p[0]*q[0]; return (float *)r;
}
for(i=0;i<N/2;i++)
{
pl[i]=p[i];
ql[i]=q[i];
}
for(i=N/2;i<N;i++)
{
ph[i-N/2]=p[i];
qh[i-N/2]=q[i];
}
for(i=0;i<N/2;i++) t1[i]=pl[i]*ph[i];
for(i=0;i<N/2;i++) t2[i]=ql[i]*qh[i];
rm=mult(t1,t2,N/2);
rl=mult(pl,ql,N/2);
rh=mult(ph,qh,N/2);
for(i=0;i<N-1;i++) r[i]=rl[i];
r[N-1]=0;
for(i=0;i<N-1;i++) r[N+i]=rh[i];
for(i=0;i<N-1;i++)
r[N/2+i]+=rm[i]-(rl[i]+rh[i]);
return (float *)r;
}
错误就是这些
(13): warning C4172: returning address of local variable or temporary
(28): error C2440: '=' : cannot convert from 'float *' to 'float [4]' There are no conversions to array types, although there are conversions to references or pointers to arrays
(29): error C2440: '=' : cannot convert from 'float *' to 'float [4]' There are no conversions to array types, although there are conversions to references or pointers to arrays
(30): error C2440: '=' : cannot convert from 'float *' to 'float [4]' There are no conversions to array types, although there are conversions to references or pointers to arrays
(36): warning C4172: returning address of local variable or temporary
我无法理解是什么原因?请帮帮我
答案 0 :(得分:2)
警告C4172:返回本地变量的地址或临时
这意味着您正在调用未定义的行为,因为您返回的变量的地址在退出某个范围时将不再存在。我可以看到一个这样的例子:
float *mult(float p[],float q[],int n)
创建本地数组r
并返回它的地址。像往常一样,还有很多其他错误,但我会停止这个错误。
你可以通过返回一个向量来避免这个问题:
std::vector<float> mult( .... ) { fill vector with values you would put in array and return it }
这只是一种可能的解决方案。这里的优点是您不必担心内存管理。
答案 1 :(得分:1)
你有几个不同的问题,但它们彼此相关。
你得到的第一个和最后一个警告是因为r
是你函数中的一个局部变量,它会在函数返回时消失 - 这意味着返回它的地址就像你一样要求麻烦。调用者将获得一个不再指向任何有意义的指针。 (很可能,很多时候代码仍然有效,但只是因为你很幸运。)
其他错误是因为你有一个返回指向数组的指针的函数,并且你试图将该返回值赋给数组变量。我不确定你是否希望(1)将数据的内容复制到数组中,或者(2)数组变量将开始引用函数返回的数据,但实际上都不会发生
这两个问题的解决方案是相同的:对数组和指针之间的差异以及实际运行的数据的位置更加清晰和谨慎。您可以采取三种主要方法来实现这一目标。
首先,您可以将数据放在C ++ vector<float>
而不是C风格的数组中。这些可以按价值传递,就像你试图做的那样,它就会工作。但是,它可能涉及大量数据复制,这可能会使您的代码比您想要的慢。
其次,您可以继续使用C样式的原始内存块,但可以使用指针而不是整个数组,并使用new
和delete
或malloc
显式分配它们和free
,并注意一切都会被释放一次。
第三,您可以继续使用C风格的数组,但是 - 而不是尝试从函数返回数组 - 将指向数组开头的指针传递给函数,并填写其新内容。这样,内存管理是mult
函数调用者的责任,如果你做得对,你可以避免在mult
本身中需要任何类型的内存分配。 (您可能会发现调用者需要传入指向某个临时空间的指针;如果您正确组织它,递归调用将能够使用相同的临时空间。)
第一种方法是最简单的。最后一个可能是表现最好的。我真的不推荐中间的那个。
答案 2 :(得分:1)
最好使数组r, rl, rm, rh
动态化,这也会消除警告和错误。
#include <iostream>
#include <vector>
using namespace std;
#define N 4
float* mult(float p[],float q[],int n)
{
float pl[N/2],ql[N/2],ph[N/2],qh[N/2];
float t1[N/2],t2[N/2];
float* r = new float[2*N-2]; // Create it dynamically so it can be safely returned
float *rl, *rm, *rh; // They don't need to be allocated because they will be assigned later down there.
int i,N2;
if(N==1)
{
r[0]=p[0]*q[0];
return r;
}
for(i=0;i<N/2;i++)
{
pl[i]=p[i];
ql[i]=q[i];
}
for(i=N/2;i<N;i++)
{
ph[i-N/2]=p[i];
qh[i-N/2]=q[i];
}
for(i=0;i<N/2;i++) t1[i]=pl[i]*ph[i];
for(i=0;i<N/2;i++) t2[i]=ql[i]*qh[i];
rm=mult(t1,t2,N/2);
rl=mult(pl,ql,N/2);
rh=mult(ph,qh,N/2);
for(i=0;i<N-1;i++) r[i]=rl[i];
r[N-1]=0;
for(i=0;i<N-1;i++) r[N+i]=rh[i];
for(i=0;i<N-1;i++)
r[N/2+i]+=rm[i]-(rl[i]+rh[i]);
return r;
}