1

I am just wondering whether it is possible for me to add/append elements to a list in C, and I would go around doing it?

e.g.

int numbers[6] = {5,3,5,1,3,6}

Let's say I wanted to add another number to the array 'numbers', how would I do that?

4 Answers4

7

Well, the original array needs to be malloc'ed, rather than on the stack. Then you can use realloc:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int * numbers = malloc(6*sizeof(int));

    for(int ii = 0; ii < 6; ++ii) {
        numbers[ii] = 5;
    }

    numbers = realloc(numbers, 7*sizeof(*numbers));
    if(!numbers) {
        printf("Memory allocation failed, sorry dude!\n");
        exit(1);
    }

    numbers[6] = 7;

    for(int ii = 0; ii< 7; ++ii) {
        printf("%d\n", numbers[ii]);
    }

    free(numbers);
}
user14717
  • 4,757
  • 2
  • 44
  • 68
  • So is it just a case of allocating more memory to the array? –  Jan 02 '15 at 02:08
  • Yes, but be careful with `realloc`, since it may copy the entire array to a different location. This is an expensive operation, in a production setting. – user14717 Jan 02 '15 at 02:28
  • [don't cast the return of malloc/realloc](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc/605858#605858), and should be `7 * sizeof(*numbers)`. check for errors in returns, call `free(numbers)`, and if `realloc` fails you lost the pointer to the memory you allocated. – ryanpattison Jan 02 '15 at 02:32
1

You would need to use realloc.

void *new_array = realloc(old_array, new_array_size);
if (!new_array_size) {
  // check for error with realloc
}
old_array = new_array;   

This is a very basic implementation of std::vector. For more info on realloc see here.

This answer is for the more general case of expanding an array in C. It assumes that you have used malloc, calloc, etc. to generate your array. If not realloc will give undefined behavior since the memory has not been allocated.

alacy
  • 4,972
  • 8
  • 30
  • 47
  • 2
    Note that using realloc on the array as defined in the original problem statement is undefined behavior. You can only use realloc on arrays that have been allocated by malloc, calloc, realloc, and friends. – Bill Lynch Jan 02 '15 at 01:54
  • You're right, that's true. I was answering a more general question rather than the OP's specific request. Not a great answer on my part. – alacy Jan 02 '15 at 01:56
  • do I need to use free() after realloc()? – Jon Nezbit Feb 28 '21 at 19:40
1

The simplest solution probably would be to make an array that is larger than it needs to be upon declaration.

Your example array has six elements, so perhaps the array would be declared to have a length of eight. This would be enough to allow two more elements to be "added". You would have to keep track of both what the actual length of the array is and the number of relevant elements it contains are (eight and six respectively).

If you wanted to "add" a third element then you would have to make a new array. The new array could be twice the length of the previous one (sixteen). Copy all the elements of the previous array to the new one and then "add" the new element.

peterh
  • 11,875
  • 18
  • 85
  • 108
asimes
  • 5,749
  • 5
  • 39
  • 76
  • points are two keys to left from the right shift – peterh Jan 02 '15 at 01:55
  • 2
    @PeterHorvath, what? – asimes Jan 02 '15 at 01:55
  • I think he is trying to imply that you should be consistent with your use periods within your answer? – alacy Jan 02 '15 at 02:01
  • Period at the end of each sentence with the exception of the last sentence before newlines... not really relevant to the OP... – asimes Jan 02 '15 at 02:02
  • Thanks for the explanation dude, it helps alot! And no, full-stops do not matter, I think most people get the gist of what he is trying to say :P –  Jan 02 '15 at 02:10
  • @asimes I agree with you. I'm not sure why it was necessary to make the comment in the first place. – alacy Jan 02 '15 at 03:22
0

The array is of fixed size and can only be extended via realloc or malloc/memcpy as others have already said. There are various schemes for making this more efficient which usually require making the array opaque and operated on by a set of functions.

If you only need a list then the FreeBSD queue primitives are probably a good place to start, they provide single and doubly linked lists. Code is a single header file. If anything it shows how to implement a robust list/queue primitive.

There are various libraries for collection management such as GTK/Glib but that comes with a whole slew of other concerns you may or may not need.

The ultimate in high level functional C is probably libCello if you don't mind pushing the language to its limits.

Andrew Hacking
  • 6,296
  • 31
  • 37