Sam
Sam

Reputation: 2347

Resizing an array in C

Say I assigned an array like so:

char* array[]={"This"};

And then later I wanted to assign array[ ] a new value so that it stores "This" and "That," is there a way that I could change the size of array so that it could hold a new number of values?

Upvotes: 7

Views: 74369

Answers (4)

hmjd
hmjd

Reputation: 121971

No, you can't change the size of an array. You could use a dynamically allocated list of char* instead and realloc() as required:

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

int main() {
    char** array = malloc(1 * sizeof(*array));

    if (array) {
        array[0] = "This";

        printf("%s\n------\n", array[0]);

        char** tmp = realloc(array, 2 * sizeof(*array));
        if (tmp) {
            array = tmp;
            array[1] = "That";

            printf("%s\n", array[0]);
            printf("%s\n", array[1]);
        }

        free(array);
    }
    return 0;
}

See online demo: https://ideone.com/ng00k.

Upvotes: 17

John Bode
John Bode

Reputation: 123458

You cannot resize array objects.

You would have to dynamically allocate the memory for array and extend it using realloc. Example:

size_t current_size = 0;

char **array = malloc((current_size + 1) * sizeof *array);
if (array)
{
  array[current_size++] = "This";
}
...
/**
 * If realloc cannot extend the buffer, it will return NULL and leave
 * the original buffer intact; however, if we assign NULL back to array,
 * we lose our handle to the original buffer, causing a memory leak, so
 * we assign the result to a temporary variable.
 */
char **tmp = realloc(array, (current_size + 1) * sizeof *array)
if (tmp)
{
  array = tmp;
  array[current_size++] = "That";
}
else
{
  // realloc failed to extend the buffer; original buffer
  // is left intact.
}

Caveats:

realloc is a relatively expensive call, so you (generally) don't want to extend your buffer one element at a time like I did here. A more common strategy is to pick an initial starting size that covers most cases, and if you need to extend the buffer, double its size.

You could abstract the resize operation into a separate function, like so:

int addItem(char ***arr, char *newElement, size_t *count, size_t *bufSize)
{
  if (*count == *bufSize)
  {
     // we've run out of room; extend the buffer
     char **tmp = realloc(**arr, 2 * *bufSize * sizeof **arr);
     if (tmp)
     {
       *arr = tmp;
       *bufSize *= 2;
     }
     else
     {
       // could not extend the buffer; return failure code
       return 0;
     }
  }
  (*arr)[(*count)++] = newElement;
}

and call it as

#define N ... // initial array size

char **array = malloc(N * sizeof *array);
size_t bufSize = N;
size_t count = 0;
...
if (addItem(&array, "This", &count, &bufSize))
  printf("# elements = %zu, buffer size = %zu\n", count, bufSize);

if (addItem(&array, "That", &count, &bufSize))
  printf("# elements = %zu, buffer size = %zu\n", count, bufSize);

This is all untested and off the top of my head; no warranties express or implied. But it should be enough to point you in the right direction.

Upvotes: 2

Ben
Ben

Reputation: 2917

There is no way to resize an array. You can simply create a new array of size 2, then copy all the data from the previous one to the new one. realloc does it for you with dynamic memory. The better way is to use data structures such as LinkedLists or Vectors which you can find more about online.

Upvotes: 3

Olaf Dietsche
Olaf Dietsche

Reputation: 74028

This is not possible. You can allocate an array of char*, though:

char **array = calloc(2, sizeof(char *));
array[0] = "This";
array[1] = "That";

Upvotes: 0

Related Questions