2

I am writing a dynamic array in C.

typedef struct __c_array {
    void**_elem;
    int  cur_size;
    int  capacity;
}c_array;

My Interface look like this:

extern void push_back_c_array ( c_array*, void *);

Now user will have to allocate memory for the element to be pushed into the array . Is there any way to avoid this using void *.

I want use this to do following

int a = 5;
push_back_c_array ( <ARRAY_PTR>, a );

Is this possible.

9
  • It's harmful to typedef the struct. It has a type already; all that's been done is to make the more code more complex, by requiring the reader to reference and remember the underlying type of the typedef. Commented Mar 31, 2011 at 6:57
  • 7
    I disagree with 'it's harmful to typedef the struct', in this case the struct will be an opaque handle for his users to use the array. Commented Mar 31, 2011 at 7:02
  • do you want the user to give you a pointer and to just store that? Commented Mar 31, 2011 at 7:03
  • @Blank Xavier, Could you please explain why typedefs are bad in C, Doesn't it make my code more simpler to write. Commented Mar 31, 2011 at 7:14
  • Note that in the last code snipped we pass an address of a (&a), not the actual value, see IanNorton's answer below. Commented Mar 31, 2011 at 7:57

4 Answers 4

2

It is possible, if you provide a version of push_back_c_array() that will copy the value provided. For this you'll need an extra argument, that specifies the size of the value:

push_back_c_array(c_array* arr, void* val, unsigned int size);

You allocate memory in heap for the new value and then do memcpy. But after that you'll need to deallocate it back. So, you'll need to remember, which values are allocated by you, and which ones - by the caller. Rather nasty... So, if you do that - do that always, and describe this convention in the documenation to your function.

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

7 Comments

Thanks, but adding size parameter will be problem from usability perspective.
Not at all. That's a common case for many C functions. (Take, for example, the same memcpy()).
@ralu: that's much more simple, I agree, but then forget about passing the stack variable pointers there.
You can pass the size at array-creation time, which should alleviate your usability concerns.
Ben, but what if Avinash passes the stack variable pointer to push_back_c_array()? That just won't work, disregarding of the initial array size. The pointer won't be valid after exiting the block, and the only way to keep the value in this case is to copy it. If there is such use case, of course. (From the question I see that there is).
|
0

You might be better served allocating a small chunk of memory (perhaps to hold unions) in the beginning, and pushing back elements until you fill it up. Then either realloc, or allocate an array twice the size and copy everything over.

Comments

0

Your example array holds items of type (void*). It holds pointers. You seem to be wanting it to hold arbitrary types. In this case and int. Do you want to store copies of inserted data or to simply store pointers given to you by the caller?

A while ago I wanted simple array like behavour for a game I was writing and came up with xrlist. A while later I wanted to store them and randomly access them so came up with xrhash.

xrlist and xrhash store user supplied pointers and expect all elements to be of the same type (xrhash has a hashcode and comparison callback function )

Comments

0

you example whit a=5 should work as long as you will use integers or any other type that has same size as int. User of generic array will want to push structs, just like your. But, big elements can not/should not should not be passed by value, but its pointer should be passed.

using generic and no being bounded on sizeof(int) bring some extra effort from user. I think that best solution is that you pass allocated pointer (void*) in function and whoever wants to take this element out, should free() this struct.

1 Comment

I agree with you for big structures, and such guidelines can be published, but for small datatype like ints, it is really inconvenient to ask user to allocate each time.

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.