0

I'm currently working on a school project. I have to develop a program that is controlling an IP and developing his specs.

I'm stuck with a bidimensionnal array of char. I don't know how to return it properly.

char** extraction_ip(char **ip){
   char *ch;
   char ipv4 [4][3];
   int i = 0;
   ch = *ip;
   *ipv4 [i]=strtok(ch, ".");
   while (ipv4 [i]!= NULL){
      i++;
      *ipv4 [i]=strtok(NULL, ".");
   }
   return ipv4;
}

AND before, i tried doing this by making a void function: enter image description here

TagZK
  • 13
  • 4
  • The usual approaches are: 1. declare a variable in the calling method, and pass a pointer to it and the size information to the function as parameters. 2. allocate it dynamically via malloc. Either way, it should probably be a struct instead of a raw array, to better communicate the meaning. – Hulk May 18 '20 at 07:22
  • or perhaps better, the more general question: https://stackoverflow.com/questions/11656532/returning-an-array-using-c – Hulk May 18 '20 at 07:28
  • This code is very confused. The main problem being that a pointer to pointer is not a 2D array and can't point at one. It can only point at the first item in an array of _pointers_, nothing else. – Lundin May 18 '20 at 07:29
  • 1
    [Correctly allocating multi-dimensional arrays](https://stackoverflow.com/questions/42094465/correctly-allocating-multi-dimensional-arrays) explains the difference between a 2D array and a pointer-based look-up table. – Lundin May 18 '20 at 07:29

3 Answers3

0

In your code, you return the local variable. It's bad idea, because in the outside of this function, ipv4 maybe does not exist.

You can define ip4 as the pointer to pointer then allocate for it.

char **ipv4 = malloc(sizeof(char *)*4); // that is allocation  for 4 pointer size.
if(!ipv4) {return NULL;} // exit function if you are failed to allocate for `ipv4`

Another thing, in your code, you use:

*ipv4 [i]=strtok(ch, ".");

It should be

ipv4 [i]=strtok(ch, ".");

Because, strtok return string value/pointer to character (char *) not a character.

The while loop should add the condition for i:

while (ipv4 [i]!= NULL && i < 4) {

Because we allocated 4 pointer for ip4.

You can also pass ipv4 as the argument of the function, then do not return anything:

void extraction_ip(char **ipv4, char **ip) {}

You can see more at: Returning a 2D char array in C

and How to return a 2D array to a function in C?

Hitokiri
  • 3,607
  • 1
  • 9
  • 29
  • I tried to do first void extraction_ip(char **ipv4, char **ip) {}, but i was blocking with some errors during my compilation. I had this: https://media.discordapp.net/attachments/620604126694342688/710509436778709042/unknown.png?width=937&height=276 – TagZK May 18 '20 at 08:08
  • change `ipv4` in main to `char **ipv4` or `char *ipv4[4]`. Or change the declaration of function `extraction_ip` to `char ipv[4][3]` or `ipv[][3]` – Hitokiri May 18 '20 at 08:37
0

you should create ipv4 array dynamically because it is local.

char **ipv4 =( int**)malloc(sizeof (char*)*4);

is for allocating 4 rows.

ipv4[i]=(char*)malloc(sizeof(char)*3);

is for allocating 3 columns in each "i" row.

Thus we created ipv4 [4][3]. returning like that

return ipv4
0

Avoid if you can...

Arrays are not first class citizens in C language, not speaking of multi-D ones, so you can only return a pointer to their first element. It can be used almost the same as a true array except that you cannot use sizeof on it, and when you return a pointer to an automatic array, the array ends its lifetime at function return and the caller is left with a dangling pointer. There are 3 ways to return arrays from a function in C:

  1. return a static array

    It solves the dangling pointer problem but leads to non thread safe functions

  2. return an allocated array

    It also solves the threading question but:

    • caller has to handle the free call
    • it is far from easy to allocate true 2D array
  3. let the caller provide the array and its size

    That way the caller has full control over the kind of memory (automatic, static, or dynamic), and you can easily use multi-D arrays if you also pass their dimensions.

BTW, you cannot use a char ** for a 2D array. 2D-arrays and array of pointers are very different objects in C language. Read this for more details...

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • I began by a void function at the beginning but i had some problems while compilating https://media.discordapp.net/attachments/620604126694342688/710509436778709042/unknown.png?width=937&height=276 – TagZK May 18 '20 at 07:40