-1

Version 1:

struct mydef_s1 {
    int argc;
    char *argv[3];
};          

struct mydef_s1   *p1 = (struct mydef_s1*) malloc (sizeof (struct mydef_s1));     
p1->argv[0] = malloc (8);
p1->argv[1] = malloc (16);
p1->argv[2] = malloc (24);

Now, I want to achieve above with the following structure declaration?

Version 2:

struct mydef_s2 {
    int argc;
    char **argv;
};  

If I am right, then following would like allocate just 8 bytes (4 for memory pointer & 4 for integer in my machine)

struct mydef_s2   *p2 = (struct mydef_s2*) malloc (sizeof (struct mydef_s2));

What should I do to do the following?

p2->argv[0]= malloc(4);
p2->argv[1]=malloc(8);
2
  • Did you mean p1->argv[2] = malloc (24);? Commented May 24, 2016 at 10:32
  • Looks like a terrible idea. How do you even know how long the allocated block is for each entry in the array? Possible an XY problem. What do you actually want to achieve? Commented May 24, 2016 at 13:02

2 Answers 2

0

In the case of a pointer to pointer like

struct mydef_s2 {
    int argc;
    char **argv;
};  

you have to first allocate the memory for argv itself, then for argv[i]s.

Something like (code is without error check)

  argv = malloc(n * sizeof*argv);  //allocate memory to hold 'n' number of 'argv[i]'s
  for (i = 0; i < n; i++)
       argv[i] = malloc(32);    //allocate individual `argv[i]`s

will do the job.

1
  • @sniper: Note that this is different from the approach in your question, which uses variable sized blocks for each pointer. If you really need a constant size, use a 2D array instead. That can be allocated/freed with a single call. Otherwise you have to track the sizes of each block. A struct with flexible array member would come in handy. Commented May 24, 2016 at 13:04
0

A pointer in C is behaving somewhat like an array. A pointer to pointer, however, is something completely different than a two dimensional array.

If you meant what you typed, i.e. - an array of a non (compiled time) known size of pointers to arrays of non compiled time known sizes of chars, then you will need to do just that. Allocate storage for the array of pointers, place that in your argv, and then initialize each position there with a pointer, possibly dynamically allocated with malloc, of the actual array of chars.

If, on the other hand, you meant a two dimensional array, you have two ways to proceed. One is to do the above, possibly saving a step by allocating the inner nesting in one malloc at one go. This is somewhat wasteful in memory.

The other option is to simulate what the compiler does for two dimensional arrays. Allocate n*m chars as a single dimension array, and jump into it by with the formula i = r*m + c, where r is the row index, m is the row size, and c is the column index.

While somewhat verbose, this is what C does when you define a two dimensional array. It is also quicker to allocate, initialize and use than the alternative.

1
  • If all rows have equal size, a 2D array is the better approach. But why do you restrict its use to compile-time sizes? Just use a VLA, e.g. char (*)[len_var] Commented May 24, 2016 at 13:07

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.