Blake Simmons
Blake Simmons

Reputation: 466

How do I use malloc() to allocate memory to store an array of strings?

I am trying to create a program that populates a fixed-size argument array using the arguments passed through the terminal. My first step is trying to create and populate the array of default argument strings, which I have succeeded in doing. However, I am now trying to use malloc() to allocate space for this array, and cannot get it to compile. I've tried everything I can think of regarding the proper syntax. I've tried doing more research into malloc() and how to use it for two dimensional arrays, but I haven't found any information that helps me. I'm stuck and not sure what to do next. Here is the code:

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#define MAX_NUM_OF_ARGS 5
#define MAX_ARG_SIZE 256

int main(int argc, char **argv) {
    printf("%s%d\n", "Length: ", argc); //for debug purposes

    // Make sure we don't have more than five arguments
    if(argc > MAX_NUM_OF_ARGS) {
        printf("%s", "Too many arguments. Must enter fewer than 4.");
    }
    // Populate the array
    else{
        char defaultArgs[] = "defaultArgs"; //create default argument array

        //allocate memory for default array
        char argumentArray[MAX_NUM_OF_ARGS][MAX_ARG_SIZE] =
            (char *)malloc(MAX_NUM_OF_ARGS * MAX_ARG_SIZE * sizeof(char));

        //populate array with default arguments
        for (int i = 0; i < MAX_NUM_OF_ARGS; i++) {
            strcpy(argumentArray[i], defaultArgs);
            printf("%s\n", argumentArray[i]);
        }

        free(argumentArray);
        return 0;
    }
}

When I try to compile I get an invalid initializer error at the (char*) cast for malloc(). I've tried casting it to (char**) and (char) and also changing the sizeof(char) to sizeof(char*) and sizeof(char**).

I am not really sure what I am doing wrong at this point and I am at a loss as far as what to even try next.

Upvotes: 2

Views: 11732

Answers (3)

Deduplicator
Deduplicator

Reputation: 45654

You cannot store an array of strings in C, as a string is a variable-length datastructure, not a simple type.
So, decide what you want:

  1. An array of fixed-length buffers storing strings of fixed (maximum) length.

    char (*p)[MAX_LEN] = malloc(n * sizeof *p);
    // Store the strings at p[0], p[1], …, p[n - 1]
    
  2. A buffer storing any number of strings consecutively.

    char* p = malloc(sum_of_string_lengths + count_of_strings);
    // Now fill in the strings one after the other, including Terminator
    
  3. An array of pointers to strings.

    char** p = malloc(n * sizeof *p);
    p[0] = strdup(source[0]);
    // ...
    // p[n - 1] = ...
    

    With strdup() the common utility-function defined like:

    char* strdup(const char* s) {
        size_t n = strlen(s) + 1;
        char* r = malloc(n);
        if (r)
            memcpy(r, s, n);
        return r;
    }
    

Upvotes: 4

Carson Harmon
Carson Harmon

Reputation: 349

Try thinking about it like this:

  • Strings are character pointers
  • You need an array of character pointers

Here is an example where I make an array of char *. Essentially the pointer returned by malloc points to an area where char * will reside. Here is an illustration of what is going on.

/*
    malloc_ret_ptr  --->  [ char * my_str1 | char * my_str2 |  char * my_str3 ]
                                   |                |                 |
                                   |                |                 |
                                   v                v                 v
                                  "Thank"           "You"            "Chicago"
*/
    int main() {

          char * my_string = "this is my string";

          char ** my_string_array;

          my_string_array = malloc(sizeof(char*)*10); //Create an array of character pointers

          //Place char * inside of char * array
          my_string_array[0] = my_string;

          return 0;
        }

Upvotes: 1

dbush
dbush

Reputation: 223739

You've declared argumentArray as a two-dimensional array of char. The malloc function returns a pointer, so you can't assign a pointer to an element of this array.

You need a pointer to store what's being returned. Actually, in this case you need a pointer to a pointer, and you'll need to call malloc multiple times, once for an array of pointers for the arguments, then again in a loop for each argument:

char **argumentArray = malloc(MAX_NUM_OF_ARGS * sizeof(char *));

for (int i=0; i<MAX_NUM_OF_ARGS; i++) {
    argumentArray[i] = malloc(MAX_ARG_SIZE);
    strcpy(argumentArray[i], defaultArgs);
    printf("%s\n", argumentArray[i]);
}

Upvotes: 3

Related Questions