R Dow wrote:
I am a bit confused here, having not programmed for some time. Any help
would be gratefully received.
If I define a couple of structures thus:
struct sfinfo {
double srate;
short ssize;
short chans;
};
typedef struct {
void *pRawBuf;
FILE *fp;
struct sfinfo info;
} SOUNDFILE;
A bit strange, since you use typedef for one struct and leave the
other as is: consistency is IMHO *a good thing* in the long run.
Also, all uppercase identifiers are generally used for macros, so
you might want to look at that again, as well.
and a function so:
void sfinfocopy(struct sfinfo *from, struct sfinfo *to) {
I would be picky to say this, but still, the first parameter should
ideally be const-qualified:
void sfinfocopy(const struct sfinfo *from, struct sfinfo *to) {
A design choice really, to indicate that this is read-only in
sfinfocopy.
to->srate = from->srate;
to->ssize = from->ssize;
to->chans = from->chans;
}
This is redundant. For such simple structures, assignment is good
enough.It wasn't there always, but has been for a while now, so you
can write:
struct sfinfo to, from;
/* fill out from */
...
to = from;
If I then do something like this:
blah(struct sfinfo *info) {
Needs a return type. The implicit int is not a good choice anymore.
Or, put in void, if you'd not want to return anything back to the
caller.
SOUNDFILE *outsfp;
outsfp = (SOUNDFILE *)malloc(sizeof(SOUNDFILE)))==NULL;
A few problems here. Let's take them apart one by one.
[1] #include <stdlib.his required to bring malloc() in scope
[2] the cast is unnecessary except for *very* few cases (your's doesn't
look like one till now, so ...)
[3] the comparison with NULL: comparison returns 1(if true) or 0
(if false), always. So, here, outsfp becomes either 0 or 1 and
[a] when it's zero you don't chek it and trying to access info
through outsfp is Undefined Behavior and will possibly
land you with a crash
[b] when it's one, you are trying to use 1, an integer as the
address of an object of type SOUNDFILE, which on most
systems will be an error. Integers and pointers are ,
interchangeable but the result is implementation defined
and it is very likely you can't have an object placed at
such an address, let alone use it.
So, ideally you should've written:[*]
outsfp = malloc(sizeof *outsfp);
and taken the trouble of testing it like this:
if ( outsfp == NULL ) {
die_horribly();
/* return error code, probably */
}
and gone on to use it when and where required.
You'd need to give outsfp some valid state first so that the copy
makes sense. So fill it in:
outsfp->pRawBuf = malloc( /*some memory, maybe?*/ );
outsfp->fp = someSndfp;
...
sfinfocopy(info, &(outsfp->info));
This is where nasal demons start flying out ;-) See above.
}
It doesn't seem to work. The expression &(outsfp->info) isn't right, is it?
No. See above.
[*] A better approach would be to club the two in one statement
-- RAII (IMHO is a good thing), like:
SOUNDFILE *outsfp = malloc(sizeof *outsfp);
/* so do we have something here? */
if ( ... ) {
...
HTH
--
Suman