Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to design libraries written in ANSI C?

Tags:

c

malloc

I want to develop a library with ANSI C.

I have a string struct:

struct libme_string
{
  char* buffer;
  int length;
};

I want to write a function, libme_create_string(), that creates and initializes a string (like constructors in C++).

Which of these methods is better for designing libme_create_string()?


Method #1

Allocate memory for string object in libme_create_string() and return it:

struct libme_string* libme_create_string(int length)
{
  // Check arguments...

  // Allocate memory for object.
  struct libme_string* str = malloc(sizeof(struct libme_string));

  // Handle memory allocation errors...

  str->buffer = malloc(length);
  str->length = length;

  // Handle memory allocation errors...

  return str;
}

void libme_delete_string(struct libme_string* str)
{
    // Check arguments...

    free(str->buffer);
    free(str);
}

Use

struct libme_string* str;
str = libme_create_string(1024);

// ...

libme_delete_string(str);
str = NULL;

Method #2

Do not allocate memory for string object in libme_create_string() function, accept it as an argument:

struct void libme_create_string(libme_string* str, int length)
{
  // Check arguments...

  // Just allocate memory for members.
  str->buffer = malloc(length);
  str->length = length;

  // Handle memory allocation errors...
}

void libme_delete_string(struct libme_string* str)
{
  // Check arguments...

  free(str->buffer);
}

Use

struct libme_string str; // << different, not a pointer!
libme_create_string(&str, 1024);

// ...

libme_delete_string(&str);

Notes

  • string just a sample.
  • Method #2 is faster, isn't it?

Lastly, are there any good design guidelines for designing libraries written in C?

like image 212
Amir Saniyan Avatar asked Dec 29 '25 02:12

Amir Saniyan


1 Answers

Personally, I would view the second version as less intuitive and more error prone.

If you're trying your hardest to encapsulate instantiation (which you should be doing anyway), then the first really is the only way to go — one step, done. The second version means that in order to have a fully initialized variable, you need to not only instantiate it, but you need to call a helper function on it immediately. That extra step is a bug waiting to happen.

like image 112
cwallenpoole Avatar answered Dec 30 '25 17:12

cwallenpoole



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!