0

I have defined a function that returns a pointer to a reversed copy of the main's argv argument. When I print the results with the string formatter %s\n the effect is strange:

#include <stdio.h>

/* Returns a pointer to a reversed copy of argv */
char **revargv(int n, char *argv[])
{
  char *cpy[n];
  char **cpyptr = cpy;
  for (int i = 0; i < n; i++)
    cpy[i] = argv[n-1-i];
  return cpyptr;
}

int main(int argc, char *argv[])
{
  char **argvr = revargv(argc-1, ++argv);
  for (int i = 1; i < argc; i++)
    printf("%s\n", *argvr++);
  return 0;
}

Now I call it from the terminal after compilation ./rev emacs lisp ruby perl python and the output is

python

Segmentation fault

If I add at least one character to the beginning of printf's formatter like

int main(int argc, char *argv[])
{
  char **argvr = revargv(argc-1, ++argv);
  for (int i = 1; i < argc; i++)
    printf(" %s\n", *argvr++);
  return 0;

the output is as I expect:

 python
 perl
 ruby
 lisp
 emacs

Can anyone help me understand why is this happening?

Update

Would it be a correct approaech to allocate memory in the function and free it up after the function call like this:

char **revargv(int n, char *argv[])
{
  char **mem = malloc(n);   /* Global memory access */
  char **mem_p = mem;
  for (int i = 0; i < n; i++) {
    *mem = argv[n-1-i];
    mem++;
  }
  return mem_p;
}

int main(int argc, char *argv[])
{
  char **argvr = revargv(argc-1, ++argv);
  char **argvr_p = argvr;
  for (int i = 1; i < argc; i++) {
    printf("%s\n", *argvr++);
  }
  free(argvr_p);
  return 0;
}
Student
  • 708
  • 4
  • 11
  • 5
    You can't return a local array. – Barmar Jul 30 '21 at 21:31
  • The above thread doesn't answer my question: why does it work with an extra space character in printf though? – Student Jul 30 '21 at 21:42
  • Does `cpyptr` which is a pointer to an automatic array become a dangling pointer when the function returns? – Student Jul 30 '21 at 21:45
  • 2
    It's purely by accident. You're causing undefined behavior. – Barmar Jul 30 '21 at 21:45
  • 4
    Yes. Any pointer to automatic data becomes invalid when the function returns. – Barmar Jul 30 '21 at 21:46
  • 1
    FYI, there's no difference between `return cpyptr` and `return cpy`, since an array automatically decays to a pointer when you return it. – Barmar Jul 30 '21 at 21:47
  • Maybe [this answer to a C++ question](https://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope/6445794#6445794) provides the explanation that you are looking for. – Andreas Wenzel Aug 02 '21 at 13:33

0 Answers0