44
char * msg = new char[65546];

want to initialize to 0 for all of them. what is the best way to do this in C++?

5YrsLaterDBA
  • 33,370
  • 43
  • 136
  • 210

10 Answers10

72
char * msg = new char[65546]();

It's known as value-initialisation, and was introduced in C++03. If you happen to find yourself trapped in a previous decade, then you'll need to use std::fill() (or memset() if you want to pretend it's C).

Note that this won't work for any value other than zero. I think C++0x will offer a way to do that, but I'm a bit behind the times so I can't comment on that.

UPDATE: it seems my ruminations on the past and future of the language aren't entirely accurate; see the comments for corrections.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • This works very well as 0 is the default integral value for a `char`. – Steve Guidi Jun 28 '10 at 17:11
  • 6
    It wasn't really "introduced in C++03". The `()` initializer was present in the original C++98 as well. While the concept of value-initialization was indeed introduced in C++03, it has no relation to this specific case. `new char[N]()` is required to produce a zero-initialized array in C++98 as well. – AnT stands with Russia Jun 28 '10 at 18:36
  • 2
    I believe neither C++0x provides a way to initialize *all* elements to a specific value. It allows `new char[65546]{1, 2, 3}` - but all remaining elements will still be initialized to `0`. – Johannes Schaub - litb Jun 28 '10 at 19:24
  • 6
    You guys allergic to std::string or vector? I see little point in using heap-allocated char buffers over these alternatives and no point to encourage otherwise as the user asked for the best C++ way. – stinky472 Jun 28 '10 at 19:38
  • @stinky: Give the user a chance to decide. – Jacob Jun 28 '10 at 19:58
  • @Peter - I guess not, but when I look at the syntax I see it "constructing" a char with a default value - as opposed to the C-ish usage of memset. – Eric Petroelje Jun 28 '10 at 21:20
  • 3
    +-0, I consider myself quite an experienced c++ programmer and I wouldn't understand that line without a comment. Use std::fill or memset instead. – Viktor Sehr Sep 21 '10 at 19:33
  • The way C++ seems to be going with 11 is making the syntax more like C#, of course with some special characters for additional control of program flow. – ZeroPhase Dec 16 '13 at 04:42
  • 1
    Everyone peeing all over char*, not really considering the fact that, most of us deal with legacy code which tends to be littered with all sorts of constructs. While new code might use string or vector, too often, we need to bounce the data back as a char* (otherwise, we get quickly into "out of scope" refactoring and all the related testing). – Jon May 03 '18 at 21:24
16

The "most C++" way to do this would be to use std::fill.

std::fill(msg, msg + 65546, 0); 
Jason
  • 36,170
  • 5
  • 26
  • 60
Peter Alexander
  • 53,344
  • 14
  • 119
  • 168
15

Absent a really good reason to do otherwise, I'd probably use:

std::vector<char> msg(65546, '\0');
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
9

what is the best way to do this in C++?

Because you asked it this way:

std::string msg(65546, 0); // all characters will be set to 0

Or:

std::vector<char> msg(65546); // all characters will be initialized to 0

If you are working with C functions which accept char* or const char*, then you can do:

some_c_function(&msg[0]);

You can also use the c_str() method on std::string if it accepts const char* or data().

The benefit of this approach is that you can do everything you want to do with a dynamically allocating char buffer but more safely, flexibly, and sometimes even more efficiently (avoiding the need to recompute string length linearly, e.g.). Best of all, you don't have to free the memory allocated manually, as the destructor will do this for you.

stinky472
  • 6,737
  • 28
  • 27
6

This method uses the 'C' memset function, and is very fast (avoids a char-by-char loop).

const uint size = 65546;
char* msg = new char[size];
memset(reinterpret_cast<void*>(msg), 0, size);
Steve Guidi
  • 19,700
  • 9
  • 74
  • 90
5
memset(msg, 0, 65546)
Eric Petroelje
  • 59,820
  • 9
  • 127
  • 177
  • Remember to `#include ` – Magnus Hoff Jun 28 '10 at 17:07
  • Is sizeof(char) guaranteed to be 1? I've never seen it not be, but unless it was guaranteed by the standard, I'd use `memset(msg,0,65546*sizeof(char));` just to be sure. – Paul Tomblin Jun 28 '10 at 17:07
  • 9
    @Paul: `sizeof(char)` is guaranteed to be 1. – Magnus Hoff Jun 28 '10 at 17:08
  • @Magnus Hoff: The size of a char is 1 on *some* implementations, but it is depending on the implementation. It is true though that the Visual c++ implementation use a size of 1 byte. – Tommy Andersen Jun 28 '10 at 17:16
  • 6
    @TommyA: sizeof(char) == 1 according to the standard. I don't have a copy of the official standard, but the C++03 draft standard says, "sizeof(char), sizeof(signed char) and sizeof(unsigned char) are 1." (5.3.3) – Fred Larson Jun 28 '10 at 17:22
  • 4
    @TommyA: I do have a copy of the standard, and it says exactly what @Fred says it says. Of course, it doesn't have to be 8 bits... – Mike Seymour Jun 28 '10 at 17:29
  • My mistake Mike, I confused the char and byte size here. – Tommy Andersen Jun 28 '10 at 21:04
  • @Tommy: Well strictly speaking "char" and "byte" are exactly the same in C++. Octet is used to refer to a set of 8 bits. – GManNickG Jun 29 '10 at 17:24
  • @GManNickG I think hell will freeze over before anyone tries to redefine byte to be anything other than 8 bits. It's just too ingrained in everything by now. – Nicu Stiurca Feb 13 '14 at 23:00
1

You can use a for loop. but don't forget the last char must be a null character !

char * msg = new char[65546];
for(int i=0;i<65545;i++)
{
    msg[i]='0';
}
msg[65545]='\0';
Xpero
  • 11
  • 1
1

The C-like method may not be as attractive as the other solutions to this question, but added here for completeness:

You can initialise with NULLs like this:

char msg[65536] = {0};

Or to use zeros consider the following:

char msg[65536] = {'0' another 65535 of these separated by comma};

But do not try it as not possible, so use memset!

In the second case, add the following after the memset if you want to use msg as a string.

msg[65536 - 1] =  '\0'

Answers to this question also provide further insight.

Community
  • 1
  • 1
Laurie Stearn
  • 959
  • 1
  • 13
  • 34
  • @HJ: Edited, thanks. OP wanted zero, if using [ASCII](http://www.theasciicode.com.ar/ascii-printable-characters/number-zero-ascii-code-48.html) '0' is the same as Chr(48)? – Laurie Stearn Dec 28 '16 at 05:43
  • The word "zero" is ambiguous when you're talking about a char, but it *usually* means null rather than the ASCII character `'0'`. I believe the OP meant an array of nulls rather than an array full of the zero character, if only because the latter is unlikely to be useful. But it doesn't hurt your answer to explain how to do both. – Harry Johnston Dec 28 '16 at 06:36
  • 1
    ... except that I *think* your second code fragment will put only a single `'0'` into the array? Did you try it out? – Harry Johnston Dec 28 '16 at 06:38
  • @HJ: Aaargh, edited again. Wishful thinking wasn't it! – Laurie Stearn Dec 28 '16 at 12:07
0

If you panic and can not assign dynamic data to a const char* in a constructor you can insert each element of a dynamic buffer piece by piece. You can even snprintf() to the buffer before making the imprint.

    client_id = new char[26] {
        buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7],buf[8],buf[9],
        buf[10],buf[11],buf[12],buf[13],buf[14],buf[15],buf[16],buf[17],buf[18],buf[19],
        buf[20],buf[21],buf[22],buf[23],buf[24],'\0'
    };

To cover up what you have been doing, maybe the editor has an option where you can set the forecolor same as the background?

Before being fired you can actually prime the const char in the header file declaration with enough space and then later assign real data in the constructor. Great!

const char*  client_id = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";

It is a const pointer and does not have to be initialized before the constructor deals with it.

const char*  client_id;
flodis
  • 1,123
  • 13
  • 9
0

NOTE: You can write at the top of the page: using namespace std, and thus avoid writing std:: at the beginning of each command.

char * msg = new char[65546]={0}; This command reset all the array to 0.

Sara Daum
  • 3
  • 2
  • 2
    This was already suggested in [this answer](https://stackoverflow.com/a/41355593/2752075). Also note that [`using namespace std;` is often considered bad practice](https://stackoverflow.com/q/1452721). – HolyBlackCat Jul 25 '22 at 10:13