manaila
manaila

Reputation: 13

C Array to Pointers

Please explain why the below code fails at line 10. How can I print values of p, i.e. Hello World.

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

int main(int argc, char **argv) {
    char ar[200] = "Hello World";
    strcat(ar, " !");
    printf("%s\n", ar);

    char **p = &ar;
    printf("%s\n", *p[0]);

    return 0;
}

EDIT:

Just to clarify more on what I want to achieve. I have a function that accepts char** as argument, hence why I want to convert char ar[200] into char**, but the application freezes.

Upvotes: 0

Views: 230

Answers (8)

Ronaldo Felipe
Ronaldo Felipe

Reputation: 402

I explain in the comments of your code.

EDIT: Do not copy following code

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

int main(int argc, char **argv) {
    char ar[200] = "Hello World";// technically an array is a pointer, so char *ar and char[] are the same
    strcat(ar, " !");// pass the pointer to treat strings
    printf("%s\n", ar);// pass the pointer to treat strings

    char **p;// here is the problem you were giving the address of your pointer to a pointer of pointer in inline wich makes more confusing
    (*p) = &ar; // here is the correct assingment
    printf("%s\n", *p);// so here you should pass  *p
    return 0;
}

EDIT: This solution is far safer in real life situations

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

int main(int argc, char **argv) {
    char ar[200] = "Hello World";// technically an array is a pointer, so char *ar and char[] are the same
    strcat(ar, " !");// pass the pointer to treat strings
    printf("%s\n", ar);// pass the pointer to treat strings

    // This solution initializing is better because it avoids editing other variables
    char *p = ar;
    char **pp = &p;

    printf("%s\n", *pp);// so here you should pass  *pp
    return 0;
}

Upvotes: -2

Peter - Reinstate Monica
Peter - Reinstate Monica

Reputation: 16016

Arrays already "decay" to the address of their first element in most contexts. This behavior differs from other variables, even from the other aggregates, structs. The reasons are rooted deep in the history of C (namely, no joke, in B1).

One of the contexts though where an array does not decay is when its address is taken: the address operator yields a pointer to array, not a pointer to pointer to char:

char arr[6] = "abcde";  // 5 letters plus '\0'
char (*parr)[6] = &arr; // pointer to array of 6 elements

Curiously enough, dereferencing this pointer twice yields the first char in the array, as if parr were a pointer to pointer to char. The reason is that *parr simply is the original array, and dereferencing that is quite normally its first element. This is likely the source of much confusion:

printf("%c", **parr);

Traditionally (i.e. in the 1970s) pointer was pointer, and their types didn't matter much. (There is a big difference though: What value does parr+1 have?) But it's nice to compile without warnings and to understand what one is doing. So how do we get your requirement, a pointer to a pointer to a char, for printing arr? The answer is, just use a pointer to a pointer!

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

int main(int argc, char **argv) {
    char ar[200] = "Hello World";
    strcat(ar, " !");
    printf("%s\n", ar);

    char *p = ar;  // pointer to char: 
                   // array "decays" to address of first char

    char **pp = &p;  // pp is a pointer to a pointer to char.
                     // The point is, it points to the "pointer to char" p.

    printf("%s\n", *pp); // *pp is what pp points to: 
                         // p, a simple pointer to char. That's what "%s"
                         // expects. p is initialized and points to 
                         // the first char in ar.

    return 0;
}


1Cf. the interesting paper by Dennis Ritchie, "The Development of the C Language", p.7

Upvotes: 4

John Coleman
John Coleman

Reputation: 51998

This question is an interesting example of the difference between arrays and pointers. It is common to think of arrays as pointers, but that isn't quite true. The fact that char ar[200] doesn't make ar into a char pointer is why you can't use a char** to point to ar. On the other hand, arrays decay to pointers in function calls, so the following code does work (though it is terribly unmotivated):

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

void printString(char ar[]){
    char **p = &ar; // as in original code
    printf("%s\n",*p);
}

int main(int argc, char **argv) {
    char ar[200] = "Hello World";
    strcat(ar, " !");
    printf("%s\n", ar);

    printString(ar); 

    return 0;
}

Upvotes: 1

Stian Skjelstad
Stian Skjelstad

Reputation: 2335

Example of when to use **pointers

#include <stdio.h>

void foo(char **bar)
{
  *bar = "some text";
}

int main(int argc, char *argv[])
{
  char *temp;

  foo (&temp);

  printf ("temp=%s\n", temp);

  return 0;
}

Upvotes: -1

Viktor Simk&#243;
Viktor Simk&#243;

Reputation: 2627

In c ar is equal to &ar, because arrays are basically memory addresses to their first elements.
So you only need a pointer to a char not a pointer to a pointer to a char.

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

int main(int argc, char **argv) {
    char ar[200] = "Hello World";
    strcat(ar, " !");
    printf("%s\n", ar);

    char *p = &ar;
    printf("%s\n", p);

    return 0;
}

Upvotes: 1

Anish Sharma
Anish Sharma

Reputation: 505

You have declared a character array and assigned value to it. If you just mention the name of the array, you are actually mentioning the base address of this array. Pointers can store address, you can define a char pointer and assign the base address of your character array to it.

for example

char ar[200]="Hello World";
char *p=a; //assign the base address of a to p;

You can then print the string using the %s format specifier with the base address of your character array(string).

printf("%s",a);// print the string "Hello World". here a is the base address
printf("%s",p);//print the string "Hello World". here p is the base address

This will work

#include <stdio.h>
#include <string.h>
int main(int argc, char **argv) {
    char ar[200] = "Hello World";
    strcat(ar, " !");
    printf("%s\n", ar);
    char *p = ar;
    printf("%s\n", p);
    return 0;
}

Edited for your convenience

char *q=a;
char **P=&q;
printf("%s",*p);

if this is what you want

Upvotes: 5

yayg
yayg

Reputation: 319

gcc     main.c   -o main
main.c: In function ‘main’:
main.c:9:16: warning: initialization from incompatible pointer type [enabled by default]
     char **p = &ar;
                ^
main.c:10:5: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=]
     printf("%s\n", *p[0]);
     ^

expects argument of type ‘char *’, but argument 2 has type ‘int’ seems very clear :P

You can print your string by changing you program by

int main(int argc, char **argv) {
    char ar[200] = "Hello World";
    strcat(ar, " !");

    char *p = ar;
    printf("%s\n", p);

    return 0;
}

Upvotes: 1

Rishikesh Raje
Rishikesh Raje

Reputation: 8614

How can I print values of p, i.e. Hello World.

You do not need a pointer to pointer for this purpose. A simple pointer will do.

char *p;
p = ar;
printf ("%s\n",p);

Upvotes: 0

Related Questions