Difference between char * and char ** (in C)

I wrote this code which is simple

#include <stdio.h> #include <string.h> void printLastLetter(char **str) { printf("%c\n",*(*str + strlen(*str) - 1)); printf("%c\n",**(str + strlen(*str) - 1)); } int main() { char *str = "1234556"; printLastLetter(&str); return 1; } 

Now, if I want to print the last char in a line, I know that the first line of printLastLetter is the correct line of code. What I do not quite understand is the difference between * str and ** str. The first is an array of characters, and the second? Also, what is the difference in memory allocation between char * str and str [10]? Thnks

+4
source share
8 answers

char* is a pointer to char, char ** is a pointer to a pointer to char.

char *ptr; DOES NOT allocate memory for characters; it allocates memory for a pointer to char.

char arr[10]; allocates 10 characters, and arr contains the address of the first character. (although arr not a pointer (not char * ), but a type of char[10] )

For demonstration: char *str = "1234556"; as follows:

 char *str; // allocate a space for char pointer on the stack str = "1234556"; // assign the address of the string literal "1234556" to str 

As @Oli Charlesworth commented, if you use a pointer to a constant string, for example, in the above example, you should declare the pointer as const - const char *str = "1234556"; , therefore, if you try to change it, which is not allowed, you will receive a compile-time error, and not a runtime access violation error, such as a segmentation error. If you are not familiar with this, check here .

Also see explanation in FAQ for comp.lang.c newsgroup .

+18
source

char ** x is a pointer to a pointer, which is useful if you want to modify an existing pointer outside its scope (for example, inside a function call).

This is important because C goes through the copy, so to change the pointer inside another function, you need to pass the address of the pointer and use the pointer to the pointer like this:

 void modify(char **s) { free(*s); // free the old array *s = malloc(10); // allocate a new array of 10 chars } int main() { char *s = malloc(5); // s points to an array of 5 chars modify(&s); // s now points to a new array of 10 chars free(s); } 

You can also use char ** to store an array of strings. However, if you dynamically highlight everything, be sure to keep track of how long the array of strings is, so that you can scroll through each element and free it.

Regarding your last question, char * str; just declares a pointer without allocated memory, whereas char str [10]; allocates an array of 10 characters in the local stack. The local array will disappear as soon as it goes out of scope, so if you want to return a string from a function, you want to use a pointer with dynamically allocated memory (malloc'd).

In addition, char * str = "Some string constant"; is also a pointer to a string constant. String constants are stored in the global data section of your compiled program and cannot be changed. You do not need to allocate memory for them, because they are compiled / hardcoded into your program, so they already occupy memory.

+11
source

The first is an array of characters, and the second

The second is a pointer to your array. Since you are passing the str address, not the pointer (str), you need this to fix it.

 printLastLetter( str ); 

and

 printf("%c\n",*(str + strlen(str) - 1)); 

makes more sense if you don't need to change the value of str.

+2
source

You may be interested in exploring this minor version of your program (the printLastLetter() function does not change, except that it is made static), and find out why the output is:

 3 X 

The output is completely deterministic - but only because I have carefully configured the list variable so that it is deterministic.

 #include <stdio.h> #include <string.h> static void printLastLetter(char **str) { printf("%c\n", *(*str + strlen(*str) - 1)); printf("%c\n", **(str + strlen(*str) - 1)); } int main(void) { char *list[] = { "123", "abc", "XYZ" }; printLastLetter(list); return 0; } 
+2
source

char ** - for a string of strings, basically - an array of character arrays. If you want to pass multiple arguments to an array of characters, you can use this provided that they are correctly distributed.

char ** x; * x will dereference and give you the first character array allocated in x. ** x will dereference the character array, which will give you the first character in the array.

0
source

for your piece of code, *str stores the address of char and **str for the address of the address of the variable char. In other words, a pointer to a pointer.

Whenever you have * str, only enough memory is allocated to store a variable of type pointer (4 bytes on a 32-bit machine). With str[10] memory is already allocated for 10 char .

0
source

**str is nothing more than (*str)[0] and the difference between *str and str[10] (in the declaration, I suppose), I think the first is just a pointer pointing to a constant string literal , which can be stored somewhere in global static memory, while the latter allocates 10 bytes of memory on the stack where the literal is stored.

0
source

char * is a pointer to a memory location. for char * str = "123456"; this is the first character of the string. "" is just a convenient way to enter an array of character values. str [10] is a way to reserve 10 characters in memory, not to mention that they are. (nb Since the last character is NULL, in fact it can only contain 9 letters. When the function accepts the * parameter, you can use the [] parameter but not vice versa.

You make this unnecessarily complicated by taking the address str before using it as a parameter. In C, you often pass the address of an object to a function because it is much faster than passing the entire object. But since it is already a pointer, you are not making the function better by passing a pointer to a pointer. Assuming you don't want to change the pointer to another line.

0
source

All Articles