return address of new memory

P

Pushker Pradhan

I have a function which should allocate memory, initialize it to some values
and return the address of the initialized memory to the calling function.
void getWaveletCoeffs(float *ld, float *hd, int *filterLen)
{
ld = (float*)malloc(2*SZFLOAT);
hd = (float*)malloc(2*SZFLOAT);

*ld++ = 0.7071;
*ld-- = 0.7071;

*hd++ = -0.7071;
*hd-- = 0.7071;

*filterLen = 2;
}

In main() I have:
float *ld = NULL;
float *hd = NULL;

getWaveletCoeffs(&ld, &hd, &filterlen);

But in main() ld and hd are still NULL, I even tried
getWaveletCoeffs(ld, hd, &filterlen);
But it returns address of some invalid memory. What is the correct way of
passing the args so that I get back the correct addresses?
 
J

Joona I Palaste

Pushker Pradhan said:
I have a function which should allocate memory, initialize it to some values
and return the address of the initialized memory to the calling function.

You are getting confused with levels of indirection. A good rule of
thumb: if you find yourself assigning something to a function parameter
(not to what the parameter points at), then you're on the wrong track.
void getWaveletCoeffs(float *ld, float *hd, int *filterLen)

Change this to:
void getWaveletCoeffs(float **ld, float **hd, int *filterLen)

Why? Because you wish to assign to *pointers* in main(). Therefore
this function needs to receive *pointers to pointers*.
If you wish to assign to "foo type", then your function must receive
"pointers to foo type". This goes for any meaning of "foo type".
{
ld = (float*)malloc(2*SZFLOAT);
hd = (float*)malloc(2*SZFLOAT);

Change these to:
*ld = malloc(2*SZFLOAT);
*hd = malloc(2*SZFLOAT);

Note that while your old code assigns to ld and hd themselves, mine
assigns to what they point at. (See the * operator?) This is what I
was talking about earlier.
*ld++ = 0.7071;
*ld-- = 0.7071;
*hd++ = -0.7071;
*hd-- = 0.7071;

These also need to be changed, to something like:
**ld = 0.7071;
*(*ld+1) = 0.7071;
**hd = -0.7071;
*(*hd+1) = 0.7071;
If I understood your logic correctly.
*filterLen = 2;
}
In main() I have:
float *ld = NULL;
float *hd = NULL;
getWaveletCoeffs(&ld, &hd, &filterlen);

This call is OK, assuming filterlen in main() is an int.
But in main() ld and hd are still NULL, I even tried
getWaveletCoeffs(ld, hd, &filterlen);

This call is wrong. Use your original call.
But it returns address of some invalid memory. What is the correct way of
passing the args so that I get back the correct addresses?

Simply keep in mind the rule of thumb I gave: "Always assign to what
the parameters point to, never to the parameters themselves", and you
should get the hang of it.

--
/-- Joona Palaste ([email protected]) ---------------------------\
| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste W++ B OP+ |
\----------------------------------------- Finland rules! ------------/
"The question of copying music from the Internet is like a two-barreled sword."
- Finnish rap artist Ezkimo
 
E

Emmanuel Delahaye

Pushker Pradhan said:
I have a function which should allocate memory, initialize it to some
values and return the address of the initialized memory to the calling
function. void getWaveletCoeffs(float *ld, float *hd, int *filterLen)
{
ld = (float*)malloc(2*SZFLOAT);
hd = (float*)malloc(2*SZFLOAT);

Modifying the value of a parameter is generally the sign of a design error.

If you want to 'return' a value, you have 2 choices :

- use the 'return' statement
- pass the address of the variable you want return a value to.

In your example, you want to return two values to two pointers to float (BTW,
why not double?). So you need to pass the address of two pointers to float,
via a pointer to the required type (that is actually 'pointer to loat'),
hence :

void getWaveletCoeffs(float **pp_ld, float *pp_hd, int *filterLen)
*ld++ = 0.7071;

Please avoid to have assignement and unary operator on the same instruction.
Your intentions are unclear, and the behaviour could be undefined. Better to
write the exactly like you want it, say:

*ld = 0.7071;
ld++;

and to leave the compiler makes its job of coding and micro-optimizaion.
*ld-- = 0.7071;

BTW, I see nothing wrong with:

ld[0] = 0.7071;
ld[1] = 0.7071;

better to avoid to modify the value returned by malloc(). 'Can hurt!
*hd++ = -0.7071;
*hd-- = 0.7071;

*filterLen = 2;
}

In main() I have:
float *ld = NULL;
float *hd = NULL;

getWaveletCoeffs(&ld, &hd, &filterlen);

This is what you should do after having fixed your interface and function
coding. Right now, its not conforming with you prototype. You should have
compile errors or at least warnings.
But in main() ld and hd are still NULL, I even tried

Sure? You never updated the value in the function. As I told you before
'Modifying the value of a parameter is generally the sign of a design error'.
 
M

Martin Ambuhl

Pushker said:
I have a function which should allocate memory, initialize it to some values
and return the address of the initialized memory to the calling function.
void getWaveletCoeffs(float *ld, float *hd, int *filterLen)
{
ld = (float*)malloc(2*SZFLOAT);
hd = (float*)malloc(2*SZFLOAT);

*ld++ = 0.7071;
*ld-- = 0.7071;

*hd++ = -0.7071;
*hd-- = 0.7071;

*filterLen = 2;
}

In main() I have:
float *ld = NULL;
float *hd = NULL;

getWaveletCoeffs(&ld, &hd, &filterlen);

But in main() ld and hd are still NULL, I even tried
getWaveletCoeffs(ld, hd, &filterlen);
But it returns address of some invalid memory. What is the correct way of
passing the args so that I get back the correct addresses?

#include <stdio.h>
#include <stdlib.h>
#include <float.h>

void getWaveletCoeffs(float **ld, float **hd, int *filterLen)
{
*ld = malloc(*filterLen * sizeof **ld);
*hd = malloc(*filterLen * sizeof **hd);
if (!*ld || !*hd) {
fputs("Who knows what to with this error?\n"
"Quiting.\n", stderr);
exit(EXIT_FAILURE);
}

(*ld)[0] = 0.7071;
(*ld)[1] = 0.7071;
(*hd)[0] = -0.7071;
(*hd)[1] = 0.7071;
}

int main(void)
{
float *ld = NULL;
float *hd = NULL;
int filterlen = 2, n;
getWaveletCoeffs(&ld, &hd, &filterlen);
printf("[output]\n");
printf("ld: %p, hd: %p\n", (void *) ld, (void *) hd);
for (n = 0; n < filterlen; n++)
printf("%.*g %.*g\n", FLT_DIG, ld[n], FLT_DIG, hd[n]);
free(ld);
free(hd);
return 0;
}


[output]
ld: 20ab8, hd: 20ac8
0.7071 -0.7071
0.7071 0.7071
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
474,079
Messages
2,570,574
Members
47,206
Latest member
Zenden

Latest Threads

Top