7

I am trying to allocate memory for a string of variable length n. Here is my attempt:

int n = 4; // Realistically, this number varies.
char* buffer = new char[n * 512]();
printf("buffer[0:3] = [%d][%d][%d][%d]\n", buffer[0], buffer[1], buffer[2], buffer[3]);

My understanding is that the inclusion of () at the end should initialize all elements to zero. However, I noticed otherwise. Here is the output to the console:

buffer[0:3] = [-120][-85][-45][0]

How do I make the new initializer work properly?

Note: I am aware that I can use std::fill, but I'm curious as to why the new initializer doesn't work as advertised.

edit: Here is my revised approach with std::fill, which gives the correct behavior. But I'd still like to know why it's necessary.

int n = 4; // Realistically, this number varies.
char* buffer = new char[n * 512]();
std::fill(&buffer[0], &buffer[n * 512], 0)
printf("buffer[0:3] = [%d][%d][%d][%d]\n", buffer[0], buffer[1], buffer[2], buffer[3]);

This outputs:

[0][0][0][0]
Community
  • 1
  • 1
tomocafe
  • 1,425
  • 4
  • 20
  • 35
  • Which compiler? That could easily cause the observed behavior. – Kevin Anderson Feb 13 '14 at 22:58
  • Well it *appears* to work as expected with gcc: http://codepad.org/X0F5bAk6 – Paul R Feb 13 '14 at 23:00
  • My compiler is `c++ (GCC) 3.4.6 20060404 (Red Hat 3.4.6-11)`. The flags I pass are: `-m32 -fPIC -O2`. – tomocafe Feb 13 '14 at 23:05
  • Are you just building a normal executable, or is this code in a library ? – Paul R Feb 13 '14 at 23:07
  • By the way, why not to use [std::array](http://msdn.microsoft.com/en-us/library/bb983093.aspx)? – Reflection Feb 13 '14 at 23:08
  • A library file, `.o` to be specific; then packaged later on to `.so`. – tomocafe Feb 13 '14 at 23:09
  • @Reflection: I need `buffer` to be passed into a function that only accepts `char *`. I tried to use a `std::string` then use the `c_str()` method to yield the corresponding `const char*`, but the function would not accept it. – tomocafe Feb 13 '14 at 23:11
  • @EvanW There's nothing wrong with the `()` - that will value initialise the elements, which is the same as zero-initialising when the type is `char`. Did you try changing the type to `signed char`? - I just want to make sure that doesn't fix it... – Joseph Mansfield Feb 13 '14 at 23:11
  • Can you test your code in a minimal standalone executable, i.e. just a `main()` with the above code in it ? I suspect it's something weird with how you're building and linking your library, so if it runs OK as a simple executable then that would support my hypothesis. – Paul R Feb 13 '14 at 23:14
  • @JosephMansfield: changing the `char` to `unsigned char` and also the format specifier did not make a difference. – tomocafe Feb 13 '14 at 23:19
  • @EvanW, what about std::array's [pointer member](http://msdn.microsoft.com/en-us/library/bb982402.aspx)? – Reflection Feb 13 '14 at 23:21
  • @PaulR: You are right, when I just have those three lines in their own executable, it works fine... but that's not surprising considering there is no memory use from other parts of the program in that short example. – tomocafe Feb 13 '14 at 23:24
  • @Reflection: I need to be able to append to this string in a loop. For `char*` I am using `sprintf()` and for my previous implementation with `std::string`, I used `append()`. Does `std::array` have something that would work like that? I looked at the reference you linked to, but didn't see anything like "append". – tomocafe Feb 13 '14 at 23:27

1 Answers1

8

My understanding is that the inclusion of () at the end should initialize all elements to zero.

You are correct. In C++98, C++03, and C++11 (all using slight differences in wording) the empty parentheses mean that the newed array will be initialized such that the char elements will ultimately be zero initialized.

c++ (GCC) 3.4.6 20060404 (Red Hat 3.4.6-11). The flags I pass are: -m32 -fPIC -O2

gcc 3.4 is nearly a decade old now and it is not surprising that would have this bug. In fact I think I vaguely recall almost exactly this bug being filed against gcc sometime in the last four or five years. That bug I believe was about the syntax:

new int[x] {};

It would be nice if writing portable code meant reading the C++ spec and then writing code with the desired behavior according to the spec. Unfortunately it more often means writing code that works around bugs in all the implementations you care about.

bames53
  • 86,085
  • 15
  • 179
  • 244