Are you seriously suggesting a solution by abusing memory like that where you tell the compiler and user you have a one-character array for the string, and then storing the actual string content way outside the array and the object?
Yes. I am seriously suggesting that. I have a feeling you've seriously mis-understood what the code is doing.
That in itself is undefined,
No, it's very well defined. (Hint: Read the ISO standard on C strings)
and then your code doesn't even consider the fact that you're not aligning consecutive structures properly to ensure that their members are aligned.
Correct. But adding code to handle that is trival.
You cannot use your objects by themselves; they are only good for storing them as pointers in an array given your code to load them.
Correct. And that is bad because?
Your code will blow up as soon as you try do treat an object as a value.
That sir, is impossible. The compiler would inform you it can't be instanced long before that could possibly happen. I'm not *that* dumb ;)
What you propose is nothing more than a pointer and a dynamic sized string, but instead of having a safe implementation of the pointer, you're way into the realm of undefined behavior.
It is a safe implementation, and it is fully defined as per the ISO standard. You might not like it, but that's not something relevant to it's validity.
As for "What you propose is nothing more than a pointer and a dynamic sized string", well, look again. You may notice that there is no char pointer - which is the entire point of doing it in the first place! It is the most compact (and efficient) way of loading string data from a file stream.
I'd also gently point out that it's used all over the place, here are a couple of samples from the Win32 SDK:
typedef struct tagMETARECORD
{
DWORD rdSize;
WORD rdFunction;
WORD rdParm[1]; ///<<<<<<<<<<<
} METARECORD;
typedef struct _RGNDATA {
RGNDATAHEADER rdh;
char Buffer[1]; ///<<<<<<<<<<<
} RGNDATA, *PRGNDATA, NEAR *NPRGNDATA, FAR *LPRGNDATA;
And now you know about the technique, you'll probably notice it in most middleware libs too ;)
It's not the only technique that exists (there are other, equally nasty looking, but valid methods), but for the scenario above, you're going to struggle to find anything that can match it for performance, and the memory usage of the loaded asset.