Originally Posted by
christop
I'm pretty sure you're referring to me.
No. What I wrote was not intended as passive-aggressive sniping, but as the literal description of my observable behaviour on this board.
Your post #9 required no comment; it is just fine as it is.
In other words, being able to modify some data stored in memory is separate from telling the OS or C library that that dynamically allocated memory is no longer needed. So, I see no problem with freeing pointers to const data.
(There is one minor wrinkle: string constants. If the interfaces will be used by other programmers, then catching errors analogous to free("foobar"); might be useful. It is not easy to catch at run time in any portable fashion -- unlike, say, NULL pointers --, but if your dynamically allocated pointers are non-const, you either have code that does casts (and thus need a careful review anyway), or you get a compile-time warning. But this basically only applies to char pointers, and it really is a minor detail. I'm not even sure it was worth pointing it out.)
Originally Posted by
christop
How would you implement free_person()?
Because I like to poison the fields when freeing, I wouldn't use const. I also prefer to keep associated data local, so my structure would more likely be
Code:
typedef struct {
size_t offset;
size_t length;
} part;
struct person {
part fname;
part lname;
size_t length;
char name[];
};
where the idea is to store the person's name in preferred representation in ->name, and slice it if needed to extract the first and last name parts. At minimum, I'd have the offset of the last name for sorting,
Code:
struct person {
size_t last;
char name[];
};
That requires C99 (or at least flexible array member) support.
For an existing codebase, I'd be happy to use your code, especially so if I saw a
Code:
/* Macro to avoid sprinkling ugly casts everywhere */
#define free_const(p) free((void *)(p))
macro somewhere near the top.