10

Hello I am new to this site, and I require some help with understanding what would be considered the "norm" while coding structures in C that require a string. Basically I am wondering which of the following ways would be considered the "industry standard" while using structures in C to keep track of ALL of the memory the structure requires:

1) Fixed Size String:

typedef struct
{
    int damage;
    char name[40];
} Item;

I can now get the size using sizeof(Item)

2) Character Array Pointer

typedef struct
{
    int damage;
    char *name;
} Item;

I know I can store the size of name using a second variable, but is there another way?

i) is there any other advantage to using the fixed size (1)

char name[40];

versus doing the following and using a pointer to a char array (2)?

char *name;

and if so, what is the advantage?

ii) Also, is the string using a pointer to a char array (2) going to be stored sequentially and immediately after the structure (immediately after the pointer to the string) or will it be stored somewhere else in memory?

iii) I wish to know how one can find the length of a char * string variable (without using a size_t, or integer value to store the length)

5
  • Why is this tagged C++? Commented Jun 30, 2014 at 19:35
  • @Rapptz: I suppose because C++ code often consumes and exposes C-compatible APIs, since they're far more compatible with other languages Commented Jun 30, 2014 at 19:36
  • 1
    For C++ it's idiomatic to use std::string - struct Foo { std::string f; };. Commented Jun 30, 2014 at 19:36
  • 1
    @CaptainObvlious: Not if you need to write that structure to disk, or return it to another language. Commented Jun 30, 2014 at 19:37
  • 1
    Fixed length strings are tempting if you want to save and load your structs in binary form on/from disk or network (and do not need portability) because it can save you a lot of headaches with serialization/deserialization. In most other cases, dynamically allocated strings are probably better since they will likely save you a lot of memory. Commented Jun 30, 2014 at 19:56

3 Answers 3

10

There are basically 3 common conventions for strings. All three are found in the wild, both for in-memory representation and storage/transmission.

  1. Fixed size. Access is very efficient, but if the actual length varies you both waste space and need one of the below methods to determine the end of the "real" content.
  2. Length prefixed. Extra space is included in the dynamically allocation, to hold the length. From the pointer you can find both the character content and the length immediately preceding it. Example: BSTR Sometimes the length is encoded to be more space efficient for short strings. Example: ASN-1
  3. Terminated. The string extends until the first occurrence of the termination character (typically NUL), and the content cannot contain that character. Variations made the termination two NUL in sequence, to allow individual NUL characters to exist in the string, which is then often treated as a packed list of strings. Other variations use an encoding such as byte stuffing (UTF-8 would also work) to guarantee that there exists some code reserved for termination that can't ever appear in the encoded version of the content.

In the third case, there's a function such as strlen to search for the terminator and find the length.

Both cases which use pointers can point to data immediately following the fixed portion of the structure, if you carefully allocate it that way. If you want to force this, then use a flexible array on the end of your structure (no pointer needed). Like this:

typedef struct
{
    int damage;
    char name[]; // terminated
} Item;

or

typedef struct
{
    int damage;
    int length_of_name;
    char name[];
} Item;
Sign up to request clarification or add additional context in comments.

9 Comments

I think it's called "flexible", not "ragged", and it's not supported by all compilers.
@anatolyg: Thanks for that. I think it's standard for C and illegal in C++?
@BenVoigt, AFAIK, yes, illegal in C++.
@BenVoigt I guess it's C99, and so not supported by Microsoft (never tried though).
@anatolyg: I thought Microsoft supported this as an extension?
|
5

1) is there any other advantage to using the fixed size (1)

char name[40];

versus doing the following and using a pointer to a char array (2)?

char *name;

and if so, what is the advantage?

With your array declared as char name[40]; space for name is already allocated and you are free to copy information into name from name[0] through name[39]. However, in the case of char *name;, it is simply a character pointer and can be used to point to an existing string in memory, but, on its own, cannot be used to copy information to until you allocate memory to hold that information. So say you have a 30 character string you want to copy to name declared as char *name;, you must first allocate with malloc 30 characters plus an additional character to hold the null-terminating character:

char *name;
name = malloc (sizeof (char) * (30 + 1));

Then you are free to copy information to/from name. An advantage of dynamically allocating is that you can realloc memory for name if the information you are storing in name grows. beyond 30 characters. An additional requirement after allocating memory for name, you are responsible for freeing the memory you have allocated when it is no longer needed. That's a rough outline of the pros/cons/requirements for using one as opposed to the other.

Comments

0

If you know the maximum length of the string you need, then you can use a character array. It does mean though that you will be using more memory than you'd typically use with dynamically allocated character arrays. Also, take a look at CString if you are using C++. You can find the length of the character array using strlen. In case of static allocation I believe it will be a part of the variable. Dynamic can be anywhere on the heap.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.