Buffer.alloc()

Allocates a new Buffer of a given size, zero-filled or pre-filled with a value you supply.

Signature
Buffer.alloc(size[, fill[, encoding]])
  • Added in Node.js v5.10.0

Parameters

ParameterTypeDescription
$sizeintegerThe desired length of the new Buffer.
$filloptionalstring | Buffer | Uint8Array | integer= 0A value to pre-fill the new Buffer with.
$encodingoptionalstring= 'utf8'If fill is a string, this is its encoding.

Return value

BufferA new Buffer of exactly size bytes, filled with zeroes unless fill is given.

Errors

Throws ERR_OUT_OF_RANGE if size is negative or larger than buffer.constants.MAX_LENGTH, ERR_INVALID_ARG_TYPE if size is not a number, and ERR_INVALID_ARG_VALUE if fill is a zero-length buffer or an invalid string for the encoding.

Changelog

  • PHP v20.0.0Invalid arguments now throw ERR_INVALID_ARG_TYPE or ERR_OUT_OF_RANGE instead of ERR_INVALID_ARG_VALUE.
  • PHP v10.0.0Filling a non-zero length buffer with a zero-length buffer now throws, and an invalid string for fill throws instead of silently producing a zero-filled buffer.

Buffer.alloc() is the safe default for creating a buffer you are about to fill in yourself. Every byte is initialised, so nothing you did not put there can leak into the output.

When to reach for it

Use it whenever you need a fixed-size region: a protocol header you will populate with writeUInt32BE, a padded fixed-width record, a scratch block for a read loop. If you already have the data, use Buffer.from() instead.

The fill argument

fill is repeated to cover the whole buffer, and it may be a byte value, a string, or another buffer. A string fill is encoded first, so Buffer.alloc(8, 'ab') repeats two bytes four times, and a multi-byte character will be repeated as its bytes, not as whole characters — a fill whose byte length does not divide size is cut off mid-character at the end.

Cost

Zeroing is a real memcpy, so allocating megabytes in a hot loop is measurably slower than Buffer.allocUnsafe(). That difference only matters when you are certain you will overwrite every byte before reading it; otherwise pay the zeroing and keep the guarantee.

Buffer.alloc(0) is valid and returns an empty buffer, which is the usual starting accumulator for a concat loop.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Build a fixed-length binary protocol header before writing fields into it.
  • Create a padded fixed-width record for a legacy flat-file format.
  • Start an empty accumulator with Buffer.alloc(0) before a concat loop.
  • Reserve a scratch block to read into with fs.read().

Frequently asked questions

What is the difference between Buffer.alloc and Buffer.allocUnsafe?

Buffer.alloc zero-fills the memory before returning it, while Buffer.allocUnsafe hands back whatever bytes were already there. Use alloc unless you are about to overwrite every byte and have measured that the zeroing matters.

How do I create an empty Buffer in Node.js?

Call Buffer.alloc(0), which returns a zero-length Buffer. It is the standard starting value for an accumulator that you grow with Buffer.concat.

Why is my Buffer.alloc buffer full of NUL characters when printed?

Because zero-filled means every byte is 0x00, and 0x00 decodes to the NUL character in UTF-8. Pass a fill value such as Buffer.alloc(n, 0x20) for spaces, or slice off the unwritten tail using the byte count that buf.write returned.

More examples

Building a binary frame header

The header is allocated at its exact size and every field is written before the buffer is used, so the zero fill is only a safety net. Reading the length back out of byte 2 shows the frame round-tripping through the same offsets a receiver would use.

Example · javascript
// version (1 byte) | type (1 byte) | payload length (4 bytes, BE)
function frame(type, payload) {
  const header = Buffer.alloc(6);
  header.writeUInt8(1, 0);
  header.writeUInt8(type, 1);
  header.writeUInt32BE(payload.length, 2);
  return Buffer.concat([header, payload], header.length + payload.length);
}

const packet = frame(7, Buffer.from('hello'));
console.log(packet.toString('hex'));   // 010700000005 68656c6c6f
console.log(packet.readUInt32BE(2));   // 5
console.log(packet.subarray(6).toString()); // hello

Fixed-width padded records

Passing a fill of 0x20 gives space padding, which is what most flat-file formats expect; the default zero fill would emit NUL bytes instead. The second call shows buf.write refusing to run past the length you gave it, so the record stays exactly 12 bytes.

Example · javascript
const SPACE = 0x20;

function record(code, city) {
  const buf = Buffer.alloc(12, SPACE);   // pad with spaces, not NULs
  buf.write(code, 0, 2, 'utf8');
  buf.write(city, 2, 10, 'utf8');
  return buf;
}

console.log(JSON.stringify(record('NL', 'Amsterdam').toString()));
// "NLAmsterdam "
console.log(JSON.stringify(record('DE', 'Frankfurt am Main').toString()));
// "DEFrankfurt " - truncated at 10 bytes

Errors alloc raises

Sizes are validated against buffer.constants.MAX_LENGTH, which is where a user-supplied length turns into a crash rather than an allocation. An empty fill buffer and a string that is not valid for its encoding both throw as of Node 10; older versions returned a zero-filled buffer instead.

Example · javascript
const { constants } = require('buffer');

for (const attempt of [
  () => Buffer.alloc(-1),
  () => Buffer.alloc(constants.MAX_LENGTH + 1),
  () => Buffer.alloc(4, Buffer.alloc(0)),
  () => Buffer.alloc(4, 'zz', 'hex')
]) {
  try {
    attempt();
    console.log('ok');
  } catch (err) {
    console.log(err.code);
  }
}
// ERR_OUT_OF_RANGE
// ERR_OUT_OF_RANGE
// ERR_INVALID_ARG_VALUE
// ERR_INVALID_ARG_VALUE

Discussion

  • Be the first to comment on this lesson.