7

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?

5
  • 2
    Note that you have declared a two-dimensional array here. I'm not sure that was your intention? Commented Oct 16, 2012 at 15:10
  • 1
    @harald: that's not a 2-dimensional array (maybe the question was changed after your comment but before the edit window closed). Commented Oct 16, 2012 at 15:42
  • 1
    @SteveJessop, technically you're right. It's an array of pointers to chars, but it's initialized as an array of pointers to strings (with one element.) May be what he wants though, it's a bit unclear from the question. Commented Oct 16, 2012 at 16:02
  • 3
    @harald: I think it is what he wants (except that array variables don't do what he wants). He starts with an array of one pointer (to "This"), later he wants an array of two pointers (one to "This" and one to "That"). Commented Oct 16, 2012 at 16:03
  • @SteveJessop, looks like you're right :) Commented Oct 16, 2012 at 16:11

4 Answers 4

17

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.

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

3 Comments

You can use a VLA, but even though the size of the array can vary at runtime, once the array has been created, you cannot change its size (until it has been destroyed and is recreated).
I ran this and it works, but I don't quite get it. How long can a string be? It looks like malloc is allocating the size of a pointer to 'array', which when I played with this code, was 8 bytes on my system. Then I increased the length of the string assigned to array[0] to 60 characters, ran the program through valgrind, which reported no problems. I don't get it.
don't you need to free() the initial malloc ?
3

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.

1 Comment

Would help to add a specific code example too, IMO.
2

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.

Comments

0

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

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.