-1

I'm trying to count the elements of the array's arrays for the allocation of memory "res," used to concatenate, including NULL terminators, every string stored in "argv". There are probably more bugs to be found, but the first I don't understand is argv[a][b] != NULL in /* length of arrays */. Why isn't this acceptable and are there other ways --without hardcoding- or passing length-- to determine number of elements?

used: http://pythontutor.com/c.html#mode=edit

char    *ft_concat_params (int argc, char **argv)
{
    int len_argc = argc - 1,
        len_argv = 0;
    char *res = NULL;

    /* length of argvs */
    for (int a = 0; a < len_argc; a++) {
      for (int b = 0;argv[a][b] != NULL; b++) {
        len_argv++;
      }
    }

    /* allocate memory res -- freed by calling function! */
    res = malloc (len_argv * sizeof * res);
    if (!res) {
      ft_putstr ("not allocated res");
      free(res);
      return NULL;
    }

    /* concate strings */
    for (int a = 0; a < len_argc; a++) {
      int b = 0;
      while (argv[a][b] != '\0') {
        res = &argv[a][b];
        b++;
      }
      res[b] = '\0';
    }

    return res;
}

int   main(void)
{
  int argc = 4;
  char argv[3][6] = {
    {'s','t','a','r','t','\0'},
    {'s','t','a','r','t','\0'},
    {'s','t','a','r','t','\0'}
  };
  char *arr;

  arr = ft_concat_params (argc, argv);
  if (!arr)       /* validate return */
      return 1;

  free(arr);
}
Mike
  • 61
  • 8
  • It looks as though you are trying to replicate the way program arguments are passed to `int main(int argc, char *argv[])` but they are not like what you are doing. – Weather Vane Mar 06 '19 at 14:52
  • '\0' is similar to (char)0 = a char that has value 0. This is used to terminate a C string, it is not the same as NULL which is a pointer to memory location 0 – MikNiller Mar 06 '19 at 14:55
  • 1
    @MikNiller - Technically both `'\0'` and `NULL` have the numeric value zero on many systems, but I agree, do not mix them up – Govind Parmar Mar 06 '19 at 14:56
  • @WeatherVane I did so because http://pythontutor.com/c.html#mode=edit appears not to have a way to pass arguments to main. How should I declare the array? – Mike Mar 06 '19 at 14:56
  • As I wrote: `int main(int argc, char *argv[])` please see [What are the arguments to main() for?](https://stackoverflow.com/questions/3734111/what-are-the-arguments-to-main-for) Edit: oh I see, the web page doesn't let you. – Weather Vane Mar 06 '19 at 14:59
  • @WeatherVane But isn't that the same if I would set the argc to the number of arguments, and argv to the actual content of arguments? And pass those to the function ft_concat_params? Edit: gotcha – Mike Mar 06 '19 at 15:04
  • No: please read the link, there are two additional array elements. `argv[0]` is a pointer to the program name, `argv[argc]` is `NULL`. – Weather Vane Mar 06 '19 at 15:05

3 Answers3

6

This line:

char *res = 'NULL'; 

Does NOT initialize the pointer to NULL. Rather, it sets to some strange, non-sensical 32-bit value.

You want to start with

char *res = NULL;  // NOTE:  No single-quotes around it.
abelenky
  • 63,815
  • 23
  • 109
  • 159
  • 2
    in fact the value is not used before to be set so `char *res;` is enough. But upvode also because your icon is perfect to explain what you probably think when you see the error ^^ – bruno Mar 06 '19 at 14:55
1
the first I don't understand is argv[a][b] != NULL
  • argv has type (char **)
  • argv[a] has type (char *)
  • argv[a][b] has type (char)

Comparing argv[a][b] with NULL is comparing a char with a pointer, which is not allowed because it doesn't make sense.

Ray Butterworth
  • 588
  • 1
  • 3
  • 18
0

The main problem is that a 2D array has nothing to do with a char**. A pointer to pointer cannot point at a 2D array. It is not a 2D array. It is not compatible with a 2D array. Forget about pointer to pointers.

Except when you have a 1D array of pointers - then a pointer-to-pointer can be used to point at the first element of that array. So if your code in main() had been char* argv[n] = { "hello", "world", ... } then your function with char** would have worked.

But it is not. You have a true 2D array in main(). So you have to change the function accordingly:

char* ft_concat_params (int x, int y, char argv[x][y])
{
  ...
  argv[i][j]  // now you can use this way of accessing
Lundin
  • 195,001
  • 40
  • 254
  • 396
  • From what I have learned so far, and tested: char *argv[] == char **argv , or does that only apply with the main function? – Mike Mar 06 '19 at 17:30
  • @Mike Arrays, when passed as argument to a function, get adjusted into a pointer to the first element of the array. So if you pass an array `char* []` to a function, the parameter will be of type `char**`, since that is a pointer to the first `char*` element in the `char* []` array. And it doesn't matter if you declare the function as `void f (char* foo[])` or `void f (char** foo)`, because the former will get silently translated into the latter. – Lundin Mar 07 '19 at 07:34