0

I have a problem trying to create a variable size array that contains strings. I have tried to create a multidimensional array, but it's too difficult. Example:

char *audio_types[8][40];           // 8 is number of string elements in the array by default; 40 is the maximum length of a string
audio_types = (char *) malloc(15);  // increasing number of strings in the array

free(audio_types);

Moreover, I was trying to create variable size pointer array. Example:

char *audio_types[40];              // 40 is the maximum length of a string
*audio_types = (char *) malloc(8);  // setting number of strings to 8

free(audio_types);

The problem is that I don't know how to create an array with variable number of string elements properly. Sorry, I am new in C programming. In the short, my code has to hold multiple string elements in one array. Example:

audio_types[0]  // some string...
audio_types[1]  // another string...
audio_types[2]  // more another sting... etc.

Hope you understand what I am trying to ask. Thank you for your attention.

6
  • char* audio_types[40]; declares an "array of 40 (char*)". Compare with char[40]* audio_types which is "a pointer to (char[40])". Often, it would be written simply as char** audio_types, accepting the array decay to "a pointer to pointers-to-characters (ie. a pointer to strings)". Commented Jun 3, 2021 at 21:49
  • malloc(15); allocates 15 bytes. If you want 15 pointers audio_types = malloc(15 * sizeof(char *)); And don't cast the return value of malloc: stackoverflow.com/questions/605845/… Commented Jun 3, 2021 at 21:52
  • If you allocate a fixed size array you can't change it. So instead use malloc right from the start and then call realloc to change the size. Commented Jun 3, 2021 at 21:53
  • char *audio_types[8][40]; is a 2D array of 320 character pointers. What you meant to write was char *audio_types[8]; which is 8 character pointers. The 40 is not needed here because the pointers in the array don't point anywhere yet - the 40 is used whe nyou create the strings that the pointers point to. Commented Jun 3, 2021 at 21:55
  • And *audio_types = (char *) malloc(8); doesn't work because *audio_types is one character and not a pointer and you are assigning an 8 byte character array to a single character. Your compiler probably printed a warning that you were doing something illegal. You probably wanted audio_types = malloc(8 * sizeof(char *)); Commented Jun 3, 2021 at 21:57

4 Answers 4

2

Maybe something like this. It will grow the size of the array when you add new types. It will also keep track of how many types you have in the array (it is needed if you resize the array dynamically and you need to know how many elements are in this array).

#define AUDIO_TYPE_LENGTH 40

typedef char audio_type[AUDIO_TYPE_LENGTH];

typedef struct
{
    size_t size;
    audio_type audio_types[];
}audioTypes_t;

audioTypes_t *AddType(audioTypes_t *types, const char *type)
{
    size_t size = types ? types -> size : 0;

    types = realloc(types, sizeof(*types) + (size + 1) * sizeof(types -> audio_types[0]));

    if(types)
    {
        strncpy(types -> audio_types[size], type, sizeof(types -> audio_types[0] - 1));
        types -> audio_types[size][sizeof(types -> audio_types[0] - 1)] = 0; //making strncpy safe
        types -> size = size + 1;
    }
    return types;
}
Sign up to request clarification or add additional context in comments.

Comments

1

You cannot change the size of an array in C. You could create a new array each time you want to resize and transfer the contents from the old array to the new one. Alternatively, you could use a list to store your strings.

Comments

1

char string[40] is an array of 40 characters that can hold 39 characters maximum (plus the string terminator) - the maximum size cannot be changed and 40 bytes of memory are used even if you store a short string containing 2 characters (plus the string terminator).

char *string is a pointer to some characters - the pointer can point anywhere: to a single character or any size array of characters. If it points to an array of characters (which you can make using malloc() then it can be thought of as a "string")

char *array[8] is an array of 8 "strings" (really it is 8 pointers to characters) The size of the array cannot be changed but the pointers can point anywhere: to a single character or any size array of characters. If the pointers point to an array of characters (which you can make using malloc() then they can be thought of as "strings")

char array[8][40] is a 2D array which you can think of as an array of 8 "strings" - where "strings" is defined as an array of 40 characters that can hold 39 characters maximum (plus the string terminator). You cannot change the size of either dimension.

char **array is a pointer to a char * - which could just be a single "string" or to an array of "strings". The sizes aren't fixed and can be dynamically created.

char *string1 = "asd"; means that string1 points to an array of 4 characters ("asd" plus the string terminator) that are in read-only memory - you cannot change the contents of the string but you can point string1 anywhere you want.

char string1[] = "asd"; means that string1 is an array of 4 characters that are filled up by the compiler with 4 characters ("asd" plus the string terminator) - you can change the contents of the array but you can't change the size.

So if you want a dynamically sized array of character strings you can do this:

#include <stdio.h>  // printf
#include <stdlib.h> // malloc, realloc, free
#include <string.h> // strcpy, strdup

int main()
{
    // make an array of 8 string pointers
    int original_size = 8;
    char **array = malloc(original_size * sizeof(char *));
    
    // point each pointer to a string
    // you don't have to do this all at once if you don't want to
    for (int i=0; i<original_size; i++)
        array[i] = malloc(40 * sizeof(char)); // max of 39 plus the terminator
    
    // array[7] is already allocated so we can just use it as a string
    strcpy(array[7],"asd"); // the last string that we malloced
    
    // reallocate the array to be bigger
    int new_size = 15;
    array = realloc(array, new_size * sizeof(char *));

    // array[14] is a pointer that doesn't point anywhere
    // so we need to allocate space before filling it in
    array[14] = strdup("qwe"); // points 3 characters plus the string terminator
    
    printf("%s\n",array[7]);
    printf("%s\n",array[14]);
    
    // free the one we made with strdup
    free(array[14]);
    
    // free the 8 we malloced
    for (int i=0; i<original_size; i++)
        free(array[i]);
    
    // now free the array we malloced and then realloced
    free(array);
    
    return 0;
}

Note: there is NO error checking in that program because I didn't want to mask the basic ideas - make sure you add error checking to any program you make

Try it at https://onlinegdb.com/XQeyOGd0C

Comments

0

When you define the array ( the char *audio_types[40]; line) in C it creates a contiguous block of memory to the 40 char pointers in the array. As memory is allocated when the array is defined you cannot make the array longer. To do that you would need a List data type, or you could create a new array when you want to add a new element which is the old one with the new element at the end.

Comments

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.