What's the difference between
char* name
which points to a constant string literal, and
const char* name
What's the difference between
char* name
which points to a constant string literal, and
const char* name
char*
is a mutable pointer to a mutable character/string.
const char*
is a mutable pointer to an immutable character/string. You cannot change the contents of the location(s) this pointer points to. Also, compilers are required to give error messages when you try to do so. For the same reason, conversion from const char *
to char*
is deprecated.
char* const
is an immutable pointer (it cannot point to any other location) but the contents of location at which it points are mutable.
const char* const
is an immutable pointer to an immutable character/string.
char *
give segmentation fault while running?
Commented
Feb 21, 2017 at 8:52
const
if I want the compiler to give error if I forgot and changed the data by mistake, right ?
Commented
Apr 6, 2019 at 22:12
char *
is created. For example: char *s = "A string"
puts "A string"
in to the code section (RO memory) of your binary. Writing to this memory seg faults. But char *s = malloc(sizeof(char) * 10)
allocates memory on the heap, and this memory section is writeable and hence doesn't seg fault on write.
char *name
You can change the char to which name
points, and also the char at which it points.
const char* name
You can change the char to which name
points, but you cannot modify the char at which it points.
correction: You can change the pointer, but not the char to which name
points to (https://msdn.microsoft.com/en-us/library/vstudio/whkd4k6a(v=vs.100).aspx, see "Examples"). In this case, the const
specifier applies to char
, not the asterisk.
According to the MSDN page and http://en.cppreference.com/w/cpp/language/declarations, the const
before the *
is part of the decl-specifier sequence, while the const
after *
is part of the declarator.
A declaration specifier sequence can be followed by multiple declarators, which is why const char * c1, c2
declares c1
as const char *
and c2
as const char
.
EDIT:
From the comments, your question seems to be asking about the difference between the two declarations when the pointer points to a string literal.
In that case, you should not modify the char to which name
points, as it could result in Undefined Behavior.
String literals may be allocated in read only memory regions (implementation defined) and an user program should not modify it in anyway. Any attempt to do so results in Undefined Behavior.
So the only difference in that case (of usage with string literals) is that the second declaration gives you a slight advantage. Compilers will usually give you a warning in case you attempt to modify the string literal in the second case.
#include <string.h>
int main()
{
char *str1 = "string Literal";
const char *str2 = "string Literal";
char source[] = "Sample string";
strcpy(str1,source); //No warning or error, just Undefined Behavior
strcpy(str2,source); //Compiler issues a warning
return 0;
}
Output:
cc1: warnings being treated as errors
prog.c: In function ‘main’:
prog.c:9: error: passing argument 1 of ‘strcpy’ discards qualifiers from pointer target type
Notice the compiler warns for the second case but not for the first.
name
points in either case.It could result in UB.
Commented
Mar 23, 2012 at 4:24
char mystring[101] = "My sample string";
const char * constcharp = mystring; // (1)
char const * charconstp = mystring; // (2) the same as (1)
char * const charpconst = mystring; // (3)
constcharp++; // ok
charconstp++; // ok
charpconst++; // compile error
constcharp[3] = '\0'; // compile error
charconstp[3] = '\0'; // compile error
charpconst[3] = '\0'; // ok
// String literals
char * lcharp = "My string literal";
const char * lconstcharp = "My string literal";
lcharp[0] = 'X'; // Segmentation fault (crash) during run-time
lconstcharp[0] = 'X'; // compile error
// *not* a string literal
const char astr[101] = "My mutable string";
astr[0] = 'X'; // compile error
((char*)astr)[0] = 'X'; // ok
char *
value gives segmentation fault since we are trying to modify a string literal (which is present in read only memory)
Commented
Feb 21, 2017 at 8:50
In neither case can you modify a string literal, regardless of whether the pointer to that string literal is declared as char *
or const char *
.
However, the difference is that if the pointer is const char *
then the compiler must give a diagnostic if you attempt to modify the pointed-to value, but if the pointer is char *
then it does not.
extern ... name
and have *name = 'X';
. On 'proper operating system', that might fail, but on embedded systems, I'd expect it to do something platform/compiler specific.
CASE 1:
char *str = "Hello";
str[0] = 'M' //Warning may be issued by compiler, and will cause segmentation fault upon running the programme
The above sets str to point to the literal value "Hello" which is hard-coded in the program's binary image, which is flagged as read-only in memory, means any change in this String literal is illegal and that would throw segmentation faults.
CASE 2:
const char *str = "Hello";
str[0] = 'M' //Compile time error
CASE 3:
char str[] = "Hello";
str[0] = 'M'; // legal and change the str = "Mello".
The question is what's the difference between
char *name
which points to a constant string literal, and
const char *cname
I.e. given
char *name = "foo";
and
const char *cname = "foo";
There is not much difference between the 2 and both can be seen as correct. Due to the long legacy of C code, the string literals have had a type of char[]
, not const char[]
, and there are lots of older code that likewise accept char *
instead of const char *
, even when they do not modify the arguments.
The principal difference of the 2 in general is that *cname
or cname[n]
will evaluate to lvalues of type const char
, whereas *name
or name[n]
will evaluate to lvalues of type char
, which are modifiable lvalues. A conforming compiler is required to produce a diagnostics message if target of the assignment is not a modifiable lvalue; it need not produce any warning on assignment to lvalues of type char
:
name[0] = 'x'; // no diagnostics *needed*
cname[0] = 'x'; // a conforming compiler *must* produce a diagnostic message
The compiler is not required to stop the compilation in either case; it is enough that it produces a warning for the assignment to cname[0]
. The resulting program is not a correct program. The behaviour of the construct is undefined. It may crash, or even worse, it might not crash, and might change the string literal in memory.
The first you can actually change if you want to, the second you can't. Read up about const
correctness (there's some nice guides about the difference). There is also char const * name
where you can't repoint it.
Actually, char* name
is not a pointer to a constant, but a pointer to a variable. You might be talking about this other question.
What is the difference between char * const and const char *?
I would add here that the latest compilers, VS 2022 for instance, do not allow char*
to be initialized with a string literal. char* ptr = "Hello";
throws an error whilst const char* ptr = "Hello";
is legal.