What's the difference between new char[10] and new char(10)
The first allocates an array of 10 char's. The second allocates one char initialized to 10.
Or:
The first should be replaced with std::vector<char>
, the second should be placed into a smart pointer.
What is the difference between char[5] and char[10]?
This is called a buffer overflow. cin
only knows the address of the array and does not check the size of allocated (or not) memory behind this address.
cout
also does not perform any check here. It starts reading chars at the provided address until it finds '\0'.
You can prevent buffer overflow in this case by explicitly limiting the number of chars that cin
accepts.
cin >> std::setw(5) >> a
What is the difference between char *name[10] and char (*name)[10]?
This declaration
char *name[10];
declares an array of 10 elements of the type char *
.
For example such an array can be initialized the following way
char *name[10] = { "Peter", "Tom", "Michael" };
All elements of the array that do not have a corresponding initializer will be implicitly initialized by NULL
. That is the above declaration is equivalent to
char *name[10] =
{
"Peter", "Tom", "Michael", NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
A pointer to the first element of the array will look like
char **p = name;
A pointer to the whole array will look like
char * ( *p )[10] = &name;
This declaration
char (*name)[10];
declares a pointer to object of the array type char[10]
.
For example if you have an array declared like
char name_list[][10] =
{
"Peter", "Tom", "Michael"
};
then you can declare a pointer to the first element of the array like
char (*name)[10] = name_list;
A pointer to the whole array can be declared like
char ( *p )[3][10] = &name_list;
Here is a demonstrative program.
#include <stdio.h>
int main(void)
{
{
char *name[10] = { "Peter", "Tom", "Michael" };
char **p1 = name;
puts( *p1 );
char * ( *p2 )[10] = &name;
puts( ( *p2 )[0] );
// or
puts( **p2 );
}
putchar( '\n' );
{
char name_list[][10] =
{
"Peter", "Tom", "Michael"
};
char ( *p1 )[10] = name_list;
puts( *p1 );
char ( *p2 )[3][10] = &name_list;
puts( ( *p2 )[0] );
// or
puts( **p2 );
}
return 0;
}
The program output is
Peter
Peter
Peter
Peter
Peter
Peter
differences between new char[n] and new (char[n])
The basic issue here is that C++ does not allow an array bound [n]
to be used in a type unless n
is a constant expression. g++ and some other compilers will sometimes allow it anyway, but it's impossible to get consistent behavior when you start mixing variable-length-arrays and templates.
The apparent exception int* p = new int[n];
works because here the [n]
is syntactically part of the new
expression, not part of the type provided to the new
, and new
does "know how" to create arrays with length determined at runtime.
// can be "constexpr" in C++11:
const int C = 12;
int main() {
int* p1 = new int[C];
int* p2 = new (int[C]);
typedef int arrtype[C];
int* p3 = new arrtype;
int n = 10;
int* p4 = new int[n];
// int* p5 = new (int[n]); // Illegal!
// typedef int arrtype2[n]; // Illegal!
// int* p6 = new arrtype2;
delete[] p1;
delete[] p2;
delete[] p3;
delete[] p4;
}
Semantically, though, after any final [C]
is used to convert a type into an array type, the new expression only cares about whether it's dealing with an array or not. All the requirements about type of the expression, whether to use new[]
and delete[]
, and so on say things like "when the allocated type is an array", not "when the array new syntax is used". So in the example above, the initializations of p1
, p2
, and p3
are all equivalent, and in all cases delete[]
is the correct deallocation form.
The initialization of p4
is valid, but the code for p5
and p6
is not correct C++. g++ would allow them anyway when not using -pedantic
, and by analogy I'd expect the initializations for p4
, p5
, and p6
to also all be equivalent. @MM's disassembly supports that conclusion.
So yes, it should be a safe improvement to remove the "extra" parentheses from this sort of expression. And the correct deletion is the delete[]
type.
Difference between char[] and new char[] when using constant lengths
The difference is the lifetime of the array. If you write:
char a[5];
then the array has a lifetime of the block it's defined in (if it's
defined in block scope), of the class object which contains it (if it's
defined in class scope) or static lifetime (if it's defined at namespace
scope). If you write:
char* b = new char[5];
, then the array has any lifetime you care to give it—you must
explicitly terminate its lifetime with:
delete [] b;
And with regards to your last question:
int const len = 5;
char d[len];
is perfectly legal, and should compile. Where there is a difference:
int len = 5; // _not_ const
char d[len]; // illegal
char* e = new char[len]; // legal
The reason for the difference is mostly one of compiler technology and
history: in the very early days, the compiler had to know the length in
order to create the array as a local variable.
What's the difference between char[] and char[10] in C++?
char[] = "here";
This is an array is size 5, automatically deduced from the 4 letters, plus an implicit null terminator ('\0') tacked onto the end. You are allowed to write and read from positions 0-4. Anything else is undefined behavior.
char[10] = "there";
This is an array is size 10, contents "there\0\0\0\0\0"
. You are allowed to write and read from positions 0-9. Anything else is undefined behavior.
char a[] = "";
This is an array of size 1, just a null terminator. When you input 9 characters into it, that's undefined behavior. (actually, using standard string input functions, you can't even safely input 1 character, because the standard string input functions automatically tack on a null terminator.
char a[] = "123456789";
This is an array of size 10, and when you input 25 characters into it, that's undefined behavior.
http://en.wikipedia.org/wiki/Undefined_behavior
c++ new/delete and char *
char *s = new char [5];
strcpy(s, "hello");
Causes Undefined behavior(UB).
You are writing beyond the bounds of allocated memery. You allocated enough memory for 5
characters but your string has 6
characters including the \0
.
Once your program has caused this UB, all bets are off and any behavior is possible.
You need:
char *s = new char [strlen("hello") + 1];
In fact the ideal solution is to use std::string
and not char *
. These are precisley the mistakes which std::string
avoids. And there is no real need of using char *
instead of std::string
in your example.
With std::string
:
- You don't need to
new
anything - You don't need to
delete
anything & - You can do everything with
std::string
, that you do withchar *
.
What does new char(size) mean in C++?
char *buf = new char(size);
It allocates only sizeof(char)
bytes and initializes it with size
— loosely equivalent to this:
char *__internal_buf = new char; //1 byte only
*__internal_buf = size; //or static_cast<char>(size);
char *buf = __internal_buf;
It is the same difference as in these two:
char x(65); //y is single element initialized to be 'A'. as 65 is 'A'
char y[65]; //y is an array of size 65
Hope that helps.
Related Topics
Function Template with an Operator
How to Set Application Icon in a Qt-Based Project
Opening a Window That Has No Title Bar with Win32
What Is Copy/Move Constructor Choosing Rule in C++? When Does Move-To-Copy Fallback Happen
Is There a Reason Declval Returns Add_Rvalue_Reference Instead of Add_Lvalue_Reference
Print Template Typename at Compile Time
Bytewise Reading of Memory: "Signed Char *" VS "Unsigned Char *"
Is There a Reason to Use Enum to Define a Single Constant in C++ Code
Race-Condition in Pthread_Once()
How to Find the Qt5 Cmake Module on Windows
What's the Point of Std::Unique_Ptr::Get
Calculating Large Factorials in C++
Why Do Some Includes Need the .H and Others Not
Creating a Lock That Preserves the Order of Locking Attempts in C++11