What is the difference between char a[] = ?string?; and char *p = ?string?;?
The first one is array the other is pointer.
The array declaration
char a[6];
requests that space for six characters be set aside, to be known by the namea
. That is, there is a location nameda
at which six characters can sit. The pointer declarationchar *p;
on the other hand, requests a place which holds a pointer. The pointer is to be known by the namep
, and can point to any char (or contiguous array of chars) anywhere.The statements
char a[] = "string";
char *p = "string";
would result in data structures which could be represented like this:
+---+---+---+---+---+---+----+
a: | s | t | r | i | n | g | \0 |
+---+---+---+---+---+---+----+
+-----+ +---+---+---+---+---+---+---+
p: | *======> | s | t | r | i | n | g |\0 |
+-----+ +---+---+---+---+---+---+---+
It is important to realize that a reference like
x[3]
generates different code depending on whetherx
is an array or a pointer. Given the declarations above, when the compiler sees the expressiona[3]
, it emits code to start at the locationa
, move three elements past it, and fetch the character there. When it sees the expressionp[3]
, it emits code to start at the locationp
, fetch the pointer value there, add three element sizes to the pointer, and finally fetch the character pointed to. In the example above, botha[3]
andp[3]
happen to be the characterl
, but the compiler gets there differently.
Source: comp.lang.c FAQ list · Question 6.2
Difference between char **p,char *p[],char p[][]
Normal Declarations (Not Function Parameters)
char **p;
declares a pointer to a pointer to char
. It reserves space for the pointer. It does not reserve any space for the pointed-to pointers or any char
.
char *p[N];
declares an array of N pointers to char
. It reserves space for N pointers. It does not reserve any space for any char
. N
must be provided explicitly or, in a definition with initializers, implicitly by letting the compiler count the initializers.
char p[M][N];
declares an array of M arrays of N char
. It reserves space for M•N char
. There are no pointers involved. N
must be provided explicitly. M
must be provided explicitly or, in a definition with initializers, implicitly by letting the compiler count the initializers.
Declarations in Function Parameters
char **p
declares a pointer to a pointer to char
. When the function is called, space is provided for that pointer (typically on a stack or in a processor register). No space is reserved for the pointed-to-pointers or any char
.
char *p[N]
is adjusted to be char **p
, so it is the same as above. The value of N
is ignored, and N
may be absent. (Some compilers may evaluate N
, so, if it is an expression with side effects, such as printf("Hello, world.\n")
, these effects may occur when the function is called. The C standard is unclear on this.)
char p[M][N]
is adjusted to be char (*p)[N]
, so it is a pointer to an array of N char
. The value of M
is ignored, and M
may be absent. N
must be provided. When the function is called, space is provided for the pointer (typically on a stack or in a processor register). No space is reserved for the array of N char
.
argv
argv
is created by the special software that calls main
. It is filled with data that the software obtains from the “environment”. You are allowed to modify the char
data in it.
In your definition char *p = "some string";
, you are not permitted to modify the data that p
points to because the C standard says that characters in a string literal may not be modified. (Technically, what it says is that it does not define the behavior if you try.) In this definition, p
is not an array; it is a pointer to the first char
in an array, and those char
are inside a string literal, and you are not permitted to modify the contents of a string literal.
In your definition char p[] = "some string";
, you may modify the contents of p
. They are not a string literal. In this case, the string literal effectively does not exist at run-time; it is only something used to specify how the array p
is initialized. Once p
is initialized, you may modify it.
The data set up for argv
is set up in a way that allows you to modify it (because the C standard specifies this).
What is the difference between chars and strings?
A char
represents a single character. A string is a series of characters.
What is the difference between char array and char pointer in C?
char*
and char[]
are different types, but it's not immediately apparent in all cases. This is because arrays decay into pointers, meaning that if an expression of type char[]
is provided where one of type char*
is expected, the compiler automatically converts the array into a pointer to its first element.
Your example function printSomething
expects a pointer, so if you try to pass an array to it like this:
char s[10] = "hello";
printSomething(s);
The compiler pretends that you wrote this:
char s[10] = "hello";
printSomething(&s[0]);
What is the difference between char s[] and char *s?
The difference here is that
char *s = "Hello world";
will place "Hello world"
in the read-only parts of the memory, and making s
a pointer to that makes any writing operation on this memory illegal.
While doing:
char s[] = "Hello world";
puts the literal string in read-only memory and copies the string to newly allocated memory on the stack. Thus making
s[0] = 'J';
legal.
Difference between const char *p = some_string and const char[] = some_string in terms of memory allocation
In your case the bytes of the string in fun1()
live in static memory. in the other function the bytes are copied from the static memory into a buffer on the stack on initialization. It is undefined to access the returned string that is returned from fun2()
because the array on the stack does not exist anymore.
fun1()
could be rewritten as
const char fun1()
{
static const char s[] = "hello";
const char* a = s;
return a;
}
fun2()
could be rewritten as
const char fun2()
{
static const char s[] = "hello";
const char a[6]; // stack allocation (5 letters + 1 zero terminator)
strcpy(a, s);
return a; // UB: return pointer to local automatic array
}
So the main reason you get the warning is that the array in fun2()
does not exist after the call. You return a pointer into the stack frame, in the same way the following code has the same problem:
struct S { int x, y; };
struct S* fun1()
{
static struct S s = { 10, 42 };
return &s; // no problem
}
struct S* fun2()
{
struct S a = { 10, 42 };
return &a; // UB
}
Difference between char *str=STRING and char str[] = STRING?
The two declarations are not the same.
char ptr[] = "string";
declares a char array of size 7
and initializes it with the characters
s
,t
,r
,i
,n
,g
and \0
. You are allowed to modify the contents of this array.
char *ptr = "string";
declares ptr
as a char pointer and initializes it with address of string literal "string"
which is read-only. Modifying a string literal is an undefined behavior. What you saw(seg fault) is one manifestation of the undefined behavior.
Related Topics
Is There a Max Array Length Limit in C++
Why Isn't Vector≪Bool≫ a Stl Container
Returning Unique_Ptr from Functions
Is Uninitialized Local Variable the Fastest Random Number Generator
Why Does C++ Disallow Anonymous Structs
Examples of Good Gotos in C or C++
Why Does C++ Not Have Reflection
What Is the Purpose of the Most Vexing Parse
How Does Virtual Inheritance Solve the "Diamond" (Multiple Inheritance) Ambiguity
How to Clear a Stringstream Variable
How to Pad an Int With Leading Zeros When Using Cout ≪≪ Operator
Function Passed as Template Argument
How Does the Import Library Work - Details
Why Should One Not Derive from C++ Std String Class
Does the C++ Standard Allow For an Uninitialized Bool to Crash a Program