15

If I have the number of items in a var called "totalstrings" and a var called "string size" that is the string size of each item, how do I dynamically allocate an array called "array?"

This is an array of strings in C, not C++.

Thanks!

2
  • 6
    It depends on what you may have tried and what didn't work. Commented Oct 4, 2011 at 18:21
  • 1
    And, of course, why you think it didn't work. Commented Oct 4, 2011 at 18:30

5 Answers 5

32

NOTE: My examples are not checking for NULL returns from malloc()... you really should do that though; you will crash if you try to use a NULL pointer.

First you have to create an array of char pointers, one for each string (char *):

char **array = malloc(totalstrings * sizeof(char *));

Next you need to allocate space for each string:

int i;
for (i = 0; i < totalstrings; ++i) {
    array[i] = (char *)malloc(stringsize+1);
}

When you're done using the array, you must remember to free() each of the pointers you've allocated. That is, loop through the array calling free() on each of its elements, and finally free(array) as well.

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

6 Comments

But malloc returning NULL usually is too serious an error to continue, anyway. We don't want to be over-paranoid, do we? And what really is wrong is the cast of malloc's return value, which in C is completely unneccessary and usually bad practice (but nevermind I come from a C++-background, too). Otherwise good answer. +1 for rembering to correctly free.
Indeed, in C casting malloc result can be dangerous if one forgets to include <stdlib.h>. Good answer otherwise.
What if each string has a different size, say, I am trying to store a list of names
@Aadishri that isn't a problem; you don't need each string malloc to be the same size, you can size them however you need.
@sivaram you must have at least an initial number of strings to begin with, and you'll want to keep a variable with the current size of your array. If you later need to expand the space, you can realloc() your array to a larger size.
|
14

The common idiom for allocating an N by M array of any type T is

T **a = malloc(N * sizeof *a);
if (a)
  for (i = 0; i < N; i++)
    a[i] = malloc(M * sizeof *a[i]);

As of the 1989 standard, you don't need to cast the result of malloc, and in fact doing so is considered bad practice (it can suppress a useful diagnostic if you forget to include stdlib.h or otherwise don't have a prototype for malloc in scope). Earlier versions of C had malloc return char *, so the cast was necessary, but the odds of you having to work with a pre-1989 compiler are pretty remote at this point. C++ does require the cast, but if you're writing C++ you should be using the new operator.

Secondly, note that I'm applying the sizeof operator to the object being allocated; the type of the expression *a is T *, and the type of *a[i] is T (where in your case, T == char). This way you don't have to worry about keeping the sizeof expression in sync with the type of the object being allocated. IOW, if you decide to use wchar instead of char, you only need to make that change in one place.

Comments

5
char** stringList = (char**)malloc(totalStrings * sizeof(char*));

for( i=0; i<totalStrings; i++ ) {
  stringList[i] = (char*)malloc(stringSize[i]+1);
}

Comments

2

I know this question is old and was already answered. I just want to point out that malloc is a system call and shouldn't be used multiple times.

It would be better to allocate one big chunk of memory and make the array point to it. Something like this :

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

#define STR_SIZE 100 //STR_SIZE doesn't have to be a constant

int main(){
        int i;
        char **arr;
        char *long_string;
        long_string = (char *)malloc(sizeof(char)*STR_SIZE*10);
        arr = malloc(sizeof(char *)*10);

        //Pointing each item of the array to an allocated memory. 
        for (i=0; i<10; i++){
                arr[i] = (long_string + STR_SIZE * i);
        }

        //Initialising the array
        for (i=0; i<10; i++){
                strcpy(arr[i], "This is a line in a\
 paragraph\n");
        }

        //Printing the items of the array
        for (i=0; i<10; i++){
                printf("%s \n", arr[i]);
        }

        //freeing the allocated memory
        free(long_string);
        free(arr);

        return 0;
}

1 Comment

malloc() isn't a system call. The system call is brk(), which enlarges the process' data segment. malloc() is the interface to the memory allocation package provided with the C library.
0

Well, first you might want to allocate space for "array", which would be an array of char * that is "totalstrings" long.

What would then be the starting and final indexes in "array"? You know the first one is 0; what's the last one?

Then, for each entry in "array", you could (if you wanted) allocate one area of memory that is "stringsize+1" (why +1, pray tell me?) long, putting the starting address of that area -- that string -- into the correct member of "array."

That would be a good start, imo.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.