K
kj
I used to program C all the time, but that was years ago. Since
then, continued use of languages like Java that take care of memory
management have made me soft and flabby. Now I have to code
something in C, and I get the feeling that I'm courting memory
leaks and segmentation faults at every turn...
I'm writing a (Flex/Bison) parser that reads some serialized
representation of an arbitrarily complex C data structure, and
cranks out the "revived" data structure at the other end. So this
code must generate a ton of C data elements (integers, floats,
strings, etc.), and compose them in arbitrarily convoluted ways.
Suppose I have this structure
typedef struct {
int bar;
baz *frobozz;
} foo;
to represent one of these data elements. Now, I want to define a
constructor that will produce these things.
Here's where I feel particularly rusty: to malloc or not to malloc.
More specifically, what would be better of these two general
strategies:
foo new_foo(int bar, baz *frobozz) {
foo ret;
ret.bar = bar;
ret.baz = copy_a_baz(frobozz);
return ret;
}
*or*
foo *new_foo(int bar, baz *frobozz) {
foo *ret;
ret = (foo *)malloc(sizeof *ret);
if (!ret) kick_up_a_fuss();
ret->bar = bar;
ret->bar = copy_a_baz(frobozz);
return ret;
}
My gut feeling is that the second one is the way to go, but I
confess that I could not provide a very solid defense for this
preference. At best I'd mumble something indistinct about stacks
and heaps, and change the subject...
What really throws me off is to consider the simpler case of
implementing a constructor for, e.g., integers. In this case, the
gut response I described above feels all wrong. For example, it
feels weird to implement new_int like this:
int *new_int(char *int_as_string) {
int *ret;
ret = (int *)malloc(sizeof *ret);
if (!ret) kick_up_a_fuss();
*ret = (int)strtol(int_as_string, NULL, 10);
return ret;
}
Instead, in this case my instinct would be to simply write
int new_int(char *int_as_string) {
int ret = (int)strtol(int_as_string, NULL, 10);
return ret;
}
or better yet
int new_int(char *int_as_string) {
return (int)strtol(int_as_string, NULL, 10);
}
Okay, my state of confusion should be evident by now. Any words
of wisdom would be much appreciated.
TIA!
kynn
--
then, continued use of languages like Java that take care of memory
management have made me soft and flabby. Now I have to code
something in C, and I get the feeling that I'm courting memory
leaks and segmentation faults at every turn...
I'm writing a (Flex/Bison) parser that reads some serialized
representation of an arbitrarily complex C data structure, and
cranks out the "revived" data structure at the other end. So this
code must generate a ton of C data elements (integers, floats,
strings, etc.), and compose them in arbitrarily convoluted ways.
Suppose I have this structure
typedef struct {
int bar;
baz *frobozz;
} foo;
to represent one of these data elements. Now, I want to define a
constructor that will produce these things.
Here's where I feel particularly rusty: to malloc or not to malloc.
More specifically, what would be better of these two general
strategies:
foo new_foo(int bar, baz *frobozz) {
foo ret;
ret.bar = bar;
ret.baz = copy_a_baz(frobozz);
return ret;
}
*or*
foo *new_foo(int bar, baz *frobozz) {
foo *ret;
ret = (foo *)malloc(sizeof *ret);
if (!ret) kick_up_a_fuss();
ret->bar = bar;
ret->bar = copy_a_baz(frobozz);
return ret;
}
My gut feeling is that the second one is the way to go, but I
confess that I could not provide a very solid defense for this
preference. At best I'd mumble something indistinct about stacks
and heaps, and change the subject...
What really throws me off is to consider the simpler case of
implementing a constructor for, e.g., integers. In this case, the
gut response I described above feels all wrong. For example, it
feels weird to implement new_int like this:
int *new_int(char *int_as_string) {
int *ret;
ret = (int *)malloc(sizeof *ret);
if (!ret) kick_up_a_fuss();
*ret = (int)strtol(int_as_string, NULL, 10);
return ret;
}
Instead, in this case my instinct would be to simply write
int new_int(char *int_as_string) {
int ret = (int)strtol(int_as_string, NULL, 10);
return ret;
}
or better yet
int new_int(char *int_as_string) {
return (int)strtol(int_as_string, NULL, 10);
}
Okay, my state of confusion should be evident by now. Any words
of wisdom would be much appreciated.
TIA!
kynn
--