-6

我写了以下递归多项式乘法,但它给了我错误,代码在这里

#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

我不明白什么是原因?请帮助我

4

3 回答 3

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 }

这只是一种可能的解决方案。这里的好处是您不必担心内存管理。

于 2012-04-30T20:21:18.117 回答
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;
}
于 2012-04-30T20:35:20.777 回答
1

你有几个不同的问题,但它们是相互关联的。

你得到的第一个和最后一个警告是因为r它是你的函数中的一个局部变量,当函数返回时它会消失——这意味着像你一样返回它的地址是在自找麻烦。调用者将获得一个不再指向任何有意义的指针。(很可能,很多时候代码仍然可以工作,但这只是因为你很幸运。)

其他错误是因为您有一个返回指向数组的指针的函数,并且您试图将该返回值分配给数组变量。我不确定您是否希望 (1) 数据的内容将被复制到数组中,或者 (2) 数组变量将开始引用函数返回的数据,但实际上两者都不会发生.

这两个问题的解决方案是相同的:对数组和指针之间的区别以及您正在操作的数据实际存在的位置要更加清晰和小心。您可以采取三种主要方法来完成这项工作。

首先,您可以将数据放在 C++ 之类的东西中,vector<float>而不是 C 样式的数组中。这些可以按值传递,与您尝试做的方式大致相同,它会正常工作。但是,它可能涉及大量数据复制,这可能会使您的代码比您想要的要慢。

其次,您可以继续使用 C 风格的原始内存块,但始终使用指针而不是数组,并使用newanddelete或 with显式分配它们,mallocfree注意所有内容都只释放一次。

第三,你可以继续使用 C 风格的数组,但是——而不是试图从你的函数返回数组——将一个指向数组开头的指针传递给函数,并填充它的新内容。这样,内存管理是你的mult函数调用者的责任,如果你做对了,你可能会避免需要任何类型的内存分配mult。(你可能会发现调用者需要传入一个指向某个临时空间的指针;如果你组织得当,递归调用将能够使用相同的临时空间。)

第一种方法是最简单的。最后一个可能是表现最好的。我真的不推荐中间那个。

于 2012-04-30T20:32:35.263 回答