-6

i have written following recursively polynomial multiplication,but it gives me errors,code is here

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

and errors are these

(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

i could not understand what is reason?please help me

Tamer Shlash
  • 9,030
  • 4
  • 42
  • 79
dato datuashvili
  • 17,789
  • 59
  • 193
  • 310
  • 3
    Please, if you are translating code from Java to C++ by trial-and-error, you need to stop posting big chunks of code on SO, and get a [decent introductory book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) on C++, to learn the basics of the language. All of your questions would be answered in one go. This is roughly your 10th question in the last 2 days that's been in this format. – Oliver Charlesworth Apr 30 '12 at 20:20
  • no i dont agree u,i is not translated from java to c++,so before somebody downvote it ,ask me dato is it translated from java to c++?it is very rude – dato datuashvili Apr 30 '12 at 20:26
  • Sorry, that was an assumption made from what you said on your previous question. Anyway, the point is the same; you need to learn the language properly; SO is not the place to do that. – Oliver Charlesworth Apr 30 '12 at 20:28
  • i am not studing c++ by this code,it is sample code which performs some task,i have tired already by downvoting,if somebody thinks that it helps me to learn something,i will start downvoting generally and will tell anybody who asks me wwhy i does such,that it is method for learn something – dato datuashvili Apr 30 '12 at 20:30
  • One does not simply downvote a random question. – mfontanini Apr 30 '12 at 20:33
  • so it means that,if somebody could not help me,just dont post anything and even dont look at my code.i need help,not studing of brain – dato datuashvili Apr 30 '12 at 20:35
  • 1
    @dato: You are not helping yourself. You need to stop posting questions like this over and over and over again, and take some time to learn the basics of C++. You will then find it very easy to answer your own questions. – Oliver Charlesworth Apr 30 '12 at 20:38
  • Exactly, all of your questions have the same format: "I have this code {CODE}. This is the compiler output {OUTPUT}. How do I fix it?". – mfontanini Apr 30 '12 at 20:39

3 Answers3

2

warning C4172: returning address of local variable or temporary

that means you are invoking undefined behaviour because you are returning the address of a variable that will cease to exist on exiting a certain scope. I can see one instance of this:

float *mult(float p[],float q[],int n)

creates local array r and returns it's address. There are plenty other errors, as usual, but I'll stop with this one.

You could avoid that problem by returning a vector:

std::vector<float> mult( .... ) { fill vector with values you would put in array and return it }

this is only one possible solution. The advantage here is that you don't have to worry about memory management.

juanchopanza
  • 216,937
  • 30
  • 383
  • 461
  • @dato there are plenty of ways. I would suggest returning an object that holds all the information that you wanted to return in the pointer, by value. – juanchopanza Apr 30 '12 at 20:31
  • sorry @juanchopanza i have not meant you in my talking,you are person who trying to help me,others are just trying to say wisdom,how to return in this case i did not understand,could you be more specific? – dato datuashvili Apr 30 '12 at 20:33
  • @dato for example, if you know how large the array you want to return is, then just make an std::vector, put the elements in, and return it by value. It will save you a lot of pain with memory management. – juanchopanza Apr 30 '12 at 20:38
1

You have a couple of different problems, but they're related to one another.

The first and last warnings you're getting are because r is a local variable within your function and it will disappear when the function returns -- which means that returning its address, as you do, is asking for trouble. The caller will get a pointer that no longer points at anything meaningful. (Most likely, a lot of the time the code will still work, but only because you got lucky.)

The other errors are because you have a function that's returning a pointer to an array, and you're trying to assign that return value to an array variable. I'm not sure whether you're hoping (1) that the contents of the data will get copied into the array, or (2) that the array variable will start referring to the data returned by the function, but neither will actually happen.

The solution to both of these problems is the same: be clearer and more careful about the difference between arrays and pointers, and about where the data you're operating on actually live. There are three main approaches you could take to make this work.

First, you could put your data in something like C++ vector<float> rather than C-style arrays. These can be passed around by value, in much the same way as you're trying to do, and it will Just Work. However, it may involve a lot of copying of data, which may make your code slower than you'd like.

Second, you could continue to use C-style raw blocks of memory, but work with pointers instead of arrays throughout and allocate them explicitly with new and delete, or with malloc and free, and be careful that everything gets freed exactly once.

Third, you could continue to use C-style arrays, but -- instead of trying to return arrays from your function -- pass a pointer to the start of the array into the function, and fill in its new contents. That way, memory management is the responsibility of the caller of your mult function, and if you do it right you can probably avoid needing any sort of memory allocation in mult itself. (You might find that the caller needs to pass in a pointer to some temporary space; the recursive calls will be able to use that same temporary space if you organize it right.)

The first approach is the simplest. The last might be the best performing. I don't really recommend the middle one.

Gareth McCaughan
  • 19,580
  • 1
  • 38
  • 57
1

It's better if you make your arrays r, rl, rm, rh dynamic, this will eliminate both warnings and errors as well.

#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;
}
Tamer Shlash
  • 9,030
  • 4
  • 42
  • 79