0

In C++ I can allocate an array of strings (say 10 strings) very easily as:

string* arrayOfString = new string[10];

however I don't know how to do it in ANSI C. I tried:

char** arrayOfString = (*(char[1000])) malloc (sizeof (*(char[1000])));

But the compiler (MinGW 3.4.5) keeps saying that it is "Syntax error". How to do it right? Thanks.

Max
  • 3,824
  • 8
  • 41
  • 62

3 Answers3

9

If each string is of same size which is known at compile time, say it is 100, then you can do this1:

typedef char cstring[100]; //cstring is a new type which is 
                           //a char array of size 100

cstring *arrstring = malloc (1000 * sizeof (cstring));

int i;
for( i = 0 ; i < 1000 ; ++i)
     strcpy(arrstring[i], "some string of size less than or equal to 100");

for( i = 0 ; i < 1000 ; ++i)
     printf("%s\n", arrstring[i]);

Demo : http://ideone.com/oNA30

1. Note that as @Eregrith pointed out in the comment that cast is not advised if you compile your code as C. However, if you compile it as C++, then you need to write (cstring*)malloc (1000 * sizeof (cstring)) but then in C++, you should avoid writing such code in the first place. A better alternative in C++ is, std::vector<std::string> as explained at the bottom of this post.

If the size of each string is not known at compile time, or each string is not of same size, then you can do this:

char **arrstring =  malloc(sizeof(char*) * 1000); //1000 strings!
int i;
for(i = 0 ; i < 1000; ++i)
     arrstring[i] = (char*) malloc(sizeof(char) * sizeOfString); 

I'm assuming same size sizeOfString for all 1000 strings. If they're different size, then you've to pass different value in each iteration, something like this:

for(i = 0 ; i < 1000; ++i)
     arrstring[i] = malloc(sizeof(char) * sizeOfEachString[i]); 

I hope that helps you, and I also hope you can do the rest yourself.


By the way, in C++, you should not do this:

string* arrayOfString = new string[10]; //avoid new as much as possible!

Instead, you should do this:

std::vector<std::string>  strings;
strings.reserve(10);
Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • 2
    Casting the return of malloc is not advised (as [this answer](http://stackoverflow.com/a/605858/1151654) explained) but is necesseray if you plan to compile your code as C++. – Eregrith Apr 12 '12 at 09:24
  • @Eregrith: Oh.. I didn't know that which is purely C thing and I don't know C-thing much. Thanks for the comment. I edited my post. – Nawaz Apr 12 '12 at 09:47
  • 2
    typedef'ing an array? really? – tbert Apr 12 '12 at 10:11
  • +1 for "avoid new as much as possible!". I can usually tell how long a person has been programming C++ by how many different places memory allocations occur in their code. – Michael Graczyk Jul 17 '12 at 22:32
1

Try this one to allocate 100 strings. Each string is at most 1000 characters long.

char** arrayOfString = (char**) malloc (sizeof(char[100][1000]));
ericzma
  • 763
  • 3
  • 9
  • 23
0
#define N  10   // Number of strings
#define M  20   // Size of the strings

/* Please check malloc return value is not NULL */

char **arrayOfString = malloc(sizeof *arrayOfString * N);

for (i = 0; i < N; i++) {
    arrayOfString[i] = malloc(M);
}
ouah
  • 142,963
  • 15
  • 272
  • 331
  • it should be for (i = 0; i < N; i++), shouldn't it? – Castilho Apr 12 '12 at 08:25
  • I think you mean `i < N` in the `for`? – hmjd Apr 12 '12 at 08:26
  • How and with what are you compiling this? I'm getting these errors with gcc bundling this up in a .cpp file including only stdio.h and stdlib.h. temp.cpp:9: error: invalid conversion from ‘void*’ to ‘char**’ temp.cpp:11: error: expected unqualified-id before ‘for’ temp.cpp:11: error: expected constructor, destructor, or type conversion before ‘<’ token temp.cpp:11: error: expected constructor, destructor, or type conversion before ‘++’ token cnorton@steamboy:~/projects/clojure/repl-test$ – octopusgrabbus Jul 17 '12 at 19:34
  • @octopusgrabbus Your filename ending with .cpp extension, asking to compile it with gcc, gcc will use the C++ language to compile it. Use `-xc` option to gcc to compile it as a C program or rename the filename extension to .c. – ouah Jul 17 '12 at 21:19
  • @octopusgrabbus I roll back your changes. I'm not sure they add something while they change the code style. Why not `void` as a function parameter? Why include stdio.h? Why { now in a new line? Why ** not bound to the function identifier? – ouah Jul 17 '12 at 22:33
  • @ouah I could not get your sample to compile. I did not use void, because the function needed to return the head of the array of strings. – octopusgrabbus Jul 18 '12 at 12:22