3

I'm a C beginner so my apologies if this doubt is too obvious.

What would be considered the most efficient way to solve this problem: Imagine that you have a char array ORIG and after working with it, you should have a new char array DEST. So, if I wanted to create a function for this goal, what would the best approach be:

  1. A function that takes only one char array parameter ( argument ORIG ) and returning a char array DEST or
  2. A void function that takes two char array arguments and does its job changing DEST as wished?

Thanks!

1
  • In C, a function that "returns an array" is not really possible in the way you'd expect from other languages, so 1 is rarely useful. Such things is C are generally done by passing the original and destination buffers into the function, which then fills the dest buffer. Commented Aug 3, 2018 at 19:23

4 Answers 4

4

This very much depends on the nature of your function.

In your first case, the function has to allocate storage for the result (or return a pointer to some static object, but this wouldn't be thread-safe). This can be the right thing to do, e.g. for a function that duplicates a string, like POSIX' strdup(). This also means the caller must use free() on the result when it is no longer needed.

The second case requires the caller to provide the storage. This is often the idiomatic way to do these things in C, because in this case, the caller could just write

char result[256];
func(result, "bla bla");

and therefore use an automatic object to hold the result. It also has the benefit that you can use the actual return value to signal errors.

Sign up to request clarification or add additional context in comments.

2 Comments

Using the return value to signal errors is an excellent point and arguably the best reason for creating the storage outside of the function
"arguably" ;) I think the flexibility about how the storage is provided is often equally important when choosing this way ;)
1

Both are ways of valid ways of doing it, but I'd suggest using the latter, since it means you can load the contents into any block of memory, while a returned array will have to be on heap, and be freed by design. Again, both are valid ways of doing things, and this is just a guideline. What should be done usually depends on the situation.

Comments

1

It depends, If you know that the length of DEST will be the same as the lenght of ORIG i would go for the 2nd approach because then you wont have to dynamiclly allocate memory for dest inside the function (and remember to free it outside the function). If the length is different you have to dynamiclly allocate memory and you can do so in two ways: 1. Like your first approach - for returning array from a function in c you have to allocate a new array and return it's address(pointer) 2. The function can recieve two argument one is ORIG and second is a double pointer to RES , because the function recieves a double pointer it can allocate an array inside and return it via the argument. 1- is more "cleaner" way in terms of code ,and easier to use in terms of user expirience(the user is the caller)

Good luck!

Comments

1

In option 1 you will have to dynamically allocate (malloc) the output array. Which means you have a potential for a memory leak. In option 2 the output array is provided for you, so there is no chance of a leak, but there is a chance that the output array is not of sufficient size and you will get a buffer overrun when writing to it.

Both methods are acceptable, there might be a small performance difference in one compared to the other, but its really down to your choice.

Personally, being a cautios programmer, I would go for option 3:

/* Returns 0 on success, 1 on failure
   Requires : inputSize <= outpuSize
              input != output
              input != null
              output != null 
*/
int DoStuff (char* output, size_t outputSize, char* input, size_t inputSize);

(Sorry if that's not proper C, its been decades:) ) (Edited in accordance with Felix Palmen's points.)

2 Comments

A size isn't always required, but it's a good idea to give that hint. Still two things: 1.) use size_t for sizes and 2.) (debatable) put output arguments first, because that's the way most C functions do it.
Sorry, its a long time since I did C, but I agree with both your points, didn't realise C has size_t.

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.