What's the Difference Between New Char[10] and New Char(10)

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 with char *.

What does new char(size) mean in C++?

char *buf = new char(size);

It allocates only sizeof(char) bytes and initializes it with sizeloosely 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



Leave a reply



Submit