Jcrack
Jcrack

Reputation: 289

When working with a C API, use character arrays or use strings and convert as needed?

I'm working with a C API and a lot of the functions take arguments that are character arrays. I've heard that using char arrays is now frowned upon. But on the other hand, using c_str() to convert the string to a char array over-and-over seems wasteful.

Are there any reasons to do it one way vs the other?

Upvotes: 4

Views: 185

Answers (5)

Some programmer dude
Some programmer dude

Reputation: 409176

Most implementations of std::string probably store the actual string as a C string anyway, so the c_str function is just an inline function that returns a pointer. So generally, I would say the proper way to go is with std::string.

Of course, if the string is intended to be modified by the function you call, then you can't use the std::string approach. Instead, you'll have to make a copy to your own buffer before calling the function, in which case using arrays may be the way to go.

Upvotes: 2

James Johnston
James Johnston

Reputation: 9492

As mentioned, c_str() is going to be inlined. But what hasn't been mentioned but what I think is one of the most important aspects of your question is that std::string follows the principles of RAII. When using std::string, you won't need to remember to free the string or need to worry about exception safety. Just make sure each instance of std::string is not destructed until the C code is done with the string. That could especially be an issue if the std::string is a temporary made by the compiler.

If your C function writes back a string, you could use a vector<char> and set the size to your desired buffer size. That way you'll still follow C++ RAII principles.

Upvotes: 2

unwind
unwind

Reputation: 399823

The c_str() call is quite likely to be inlined—it's very small in terms of the required code. I would use std::string if that's the only thing holding you back.

Of course, if you're very worried, this standard advice applies:

  1. Profile it
  2. Read the assembly

Also be aware that this is a micro-optimization; you're quite likely to be wasting development time worrying about something completely different than from what you should be worrying about.

Upvotes: 10

James Kanze
James Kanze

Reputation: 153919

It depends on what you're doing, and what the interface functions are doing. At one extreme, I don't think anyone would recommend converting a string literal to an std::string, just so you can call c_str on it. At the other: any code building up strings dynamically should use std::string. Functions like strcpy and strcat are invitations to buffer overflow. Between two, it depends. I'd say that the criteria should be ease and safety: anytime something is easier or safer to do using std::string, use std::string. As long as what you're doing doesn't require dynamic allocation of char[], and things like operator+ on strings wouldn't be used, you can use char[].

Upvotes: 2

Matthieu M.
Matthieu M.

Reputation: 299820

There is a very simple reason to use string: it works.

Working with C-strings is a pain:

  • manual memory allocation and deallocation is error-prone
  • the interface itself is error-prone (lack of null character termination, off-by-one errors and buffer overflows are common)
  • the operations are inefficient (strlen, strcpy and strcat) because the length need be recomputed at each time

I really see no good reason to ever work with C-strings.

It's such a pain that many platforms have provided their own specific operations and that a number of "better strings" have been proposed (oh, the joy of having multiple standards).

Upvotes: 1

Related Questions