0

Why it is not working... It should be working, right? gcc have problem with this line, but why?

render_history(history, 2);

Sorry for bothering. I am just a beginner.

 #include <stdio.h>

void render_history(char** history, const int entry);

int main()
{
char* history[3][4];

history[0][0] = "1234";
history[1][0] = "5678";
history[2][0] = "9012";

render_history(history, 2); //??
return 0;
}


void render_history(char** history, const int entry)
{
// print "9012" 
}
M3Lee OP
  • 33
  • 6
  • 1
    Try this instead "void render_history(char history[][4], const int entry);" You have to specify the second dimension. – Austin Stephens May 19 '18 at 17:51
  • 1
    Double pointer is not equal to 2d array. – danglingpointer May 19 '18 at 17:52
  • Do you know how arguments are passed to the `main` function? The `argv` argument? It's an array of strings, an array of pointers. Which seems to be what you want instead of an array of arrays of pointers. What you have now is, basically, somewhat equivalent to a **3d** array. – Some programmer dude May 19 '18 at 17:54
  • 1
    Be careful, @AustinStephens: the OP has a 2D array of `char *` (not `char`), so the needed parameter type would be `char * history[][4]`, or, equivalently, `char * (*history)[4]`. – John Bollinger May 19 '18 at 18:01
  • 1
    As for why it doesn't work, it's because `history` decays to a pointer to an arrays of four pointers, `char *(*)[4]`, which is very different from `char **`. If you had e.g. `char history[3][5]`, or `char *history[3]` it would be a very different matter. – Some programmer dude May 19 '18 at 18:02
  • [Question 6.18](http://c-faq.com/aryptr/pass2dary.html) in the [C FAQ list](http://c-faq.com/). – Steve Summit May 19 '18 at 18:03
  • Possible duplicate of [Doesn't a 2D array decay to pointer to pointer](https://stackoverflow.com/questions/22987042/doesnt-a-2d-array-decay-to-pointer-to-pointer) – Steve Summit May 19 '18 at 18:06
  • You probably also want to avoid the variable shadowing by changing what you pass to render_history() or the parameter name in render_history(). – Austin Stephens May 19 '18 at 18:23

2 Answers2

2

gcc have problem with this line, but why?

Because the type is wrong. char* history[3][4]; can't be passed as char**. They are incompatible types.

Try something like:

#include <stdio.h>

void render_history(char* (*history)[4] , const int entry)
{
   printf("%s\n", history[entry][0]);
} 

int main()
{
    char* history[3][4];

    history[0][0] = "1234";
    history[1][0] = "5678";
    history[2][0] = "9012";

    render_history(history, 2);
    return 0;
}
Support Ukraine
  • 42,271
  • 4
  • 38
  • 63
1

As mentioned above double pointer not equal to 2D array. You can also use pointer to pointer of char. char **history. And with this you have several option:

1) Use compound literals

#include <stdio.h>

void render_history(const char **history, const int entry)
{
    printf("%s\n", history[entry]);
}

int main(void)
{
    const char **history = (const char *[]) { "1234", "5678", "9012", NULL};
    render_history(history, 2);  
    return 0;
}

If you need change your data later

2) Use dynamic memory allocation with malloc

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void render_history(char **history, const int entry)
{
    printf("%s\n", history[entry]);
}

int main(void)
{
    char **history = malloc(3 * sizeof(char *));

    for (int i = 0; i < 3; ++i)
    {
        history[i] = malloc(4 * sizeof(char));
    }

    strcpy(history[0], "1234");
    strcpy(history[1], "5678");
    strcpy(history[2], "9012");
    history[3] = NULL;

    render_history(history, 2);
    return 0;
}

If you use 2nd option dont forget free memory after use.

Nick S
  • 1,299
  • 1
  • 11
  • 23