// decAlloc takes a value and returns a settable value that can
 // be assigned to. If the value is a pointer, decAlloc guarantees it points to storage.
+// The callers to the individual decoders are expected to have used decAlloc.
+// The individual decoders don't need to it.
 func decAlloc(v reflect.Value) reflect.Value {
        for v.Kind() == reflect.Ptr {
                if v.IsNil() {
 
 // decBool decodes a uint and stores it as a boolean in value.
 func decBool(i *decInstr, state *decoderState, value reflect.Value) {
-       decAlloc(value).SetBool(state.decodeUint() != 0)
+       value.SetBool(state.decodeUint() != 0)
 }
 
 // decInt8 decodes an integer and stores it as an int8 in value.
        if v < math.MinInt8 || math.MaxInt8 < v {
                error_(i.ovfl)
        }
-       decAlloc(value).SetInt(v)
+       value.SetInt(v)
 }
 
 // decUint8 decodes an unsigned integer and stores it as a uint8 in value.
        if math.MaxUint8 < v {
                error_(i.ovfl)
        }
-       decAlloc(value).SetUint(v)
+       value.SetUint(v)
 }
 
 // decInt16 decodes an integer and stores it as an int16 in value.
        if v < math.MinInt16 || math.MaxInt16 < v {
                error_(i.ovfl)
        }
-       decAlloc(value).SetInt(v)
+       value.SetInt(v)
 }
 
 // decUint16 decodes an unsigned integer and stores it as a uint16 in value.
        if math.MaxUint16 < v {
                error_(i.ovfl)
        }
-       decAlloc(value).SetUint(v)
+       value.SetUint(v)
 }
 
 // decInt32 decodes an integer and stores it as an int32 in value.
        if v < math.MinInt32 || math.MaxInt32 < v {
                error_(i.ovfl)
        }
-       decAlloc(value).SetInt(v)
+       value.SetInt(v)
 }
 
 // decUint32 decodes an unsigned integer and stores it as a uint32 in value.
        if math.MaxUint32 < v {
                error_(i.ovfl)
        }
-       decAlloc(value).SetUint(v)
+       value.SetUint(v)
 }
 
 // decInt64 decodes an integer and stores it as an int64 in value.
 func decInt64(i *decInstr, state *decoderState, value reflect.Value) {
        v := state.decodeInt()
-       decAlloc(value).SetInt(v)
+       value.SetInt(v)
 }
 
 // decUint64 decodes an unsigned integer and stores it as a uint64 in value.
 func decUint64(i *decInstr, state *decoderState, value reflect.Value) {
        v := state.decodeUint()
-       decAlloc(value).SetUint(v)
+       value.SetUint(v)
 }
 
 // Floating-point numbers are transmitted as uint64s holding the bits
 // decFloat32 decodes an unsigned integer, treats it as a 32-bit floating-point
 // number, and stores it in value.
 func decFloat32(i *decInstr, state *decoderState, value reflect.Value) {
-       decAlloc(value).SetFloat(float32FromBits(i, state.decodeUint()))
+       value.SetFloat(float32FromBits(i, state.decodeUint()))
 }
 
 // decFloat64 decodes an unsigned integer, treats it as a 64-bit floating-point
 // number, and stores it in value.
 func decFloat64(i *decInstr, state *decoderState, value reflect.Value) {
-       decAlloc(value).SetFloat(float64FromBits(state.decodeUint()))
+       value.SetFloat(float64FromBits(state.decodeUint()))
 }
 
 // decComplex64 decodes a pair of unsigned integers, treats them as a
 func decComplex64(i *decInstr, state *decoderState, value reflect.Value) {
        real := float32FromBits(i, state.decodeUint())
        imag := float32FromBits(i, state.decodeUint())
-       decAlloc(value).SetComplex(complex(real, imag))
+       value.SetComplex(complex(real, imag))
 }
 
 // decComplex128 decodes a pair of unsigned integers, treats them as a
 func decComplex128(i *decInstr, state *decoderState, value reflect.Value) {
        real := float64FromBits(state.decodeUint())
        imag := float64FromBits(state.decodeUint())
-       decAlloc(value).SetComplex(complex(real, imag))
+       value.SetComplex(complex(real, imag))
 }
 
 // decUint8Slice decodes a byte slice and stores in value a slice header
        if n > state.b.Len() {
                errorf("%s data too long for buffer: %d", value.Type(), n)
        }
-       value = decAlloc(value)
        if value.Cap() < n {
                value.Set(reflect.MakeSlice(value.Type(), n, n))
        } else {
        if _, err := state.b.Read(data); err != nil {
                errorf("error decoding string: %s", err)
        }
-       decAlloc(value).SetString(string(data))
+       value.SetString(string(data))
 }
 
 // ignoreUint8Array skips over the data for a byte slice value with no destination.
 // This state cannot arise for decodeSingle, which is called directly
 // from the user's value, not from the innards of an engine.
 func (dec *Decoder) decodeStruct(engine *decEngine, ut *userTypeInfo, value reflect.Value) {
-       value = decAlloc(value)
-       //      println(value.Kind() == reflect.Ptr)
        state := dec.newDecoderState(&dec.buf)
        defer dec.freeDecoderState(state)
        state.fieldnum = -1
                if instr.index != nil {
                        // Otherwise the field is unknown to us and instr.op is an ignore op.
                        field = value.FieldByIndex(instr.index)
+                       if field.Kind() == reflect.Ptr {
+                               field = decAlloc(field)
+                       }
                }
                instr.op(instr, state, field)
                state.fieldnum = fieldnum
 // decodeArrayHelper does the work for decoding arrays and slices.
 func (dec *Decoder) decodeArrayHelper(state *decoderState, value reflect.Value, elemOp decOp, length int, ovfl error) {
        instr := &decInstr{elemOp, 0, nil, ovfl}
+       isPtr := value.Type().Elem().Kind() == reflect.Ptr
        for i := 0; i < length; i++ {
                if state.b.Len() == 0 {
                        errorf("decoding array or slice: length exceeds input size (%d elements)", length)
                }
-               elemOp(instr, state, value.Index(i))
+               v := value.Index(i)
+               if isPtr {
+                       v = decAlloc(v)
+               }
+               elemOp(instr, state, v)
        }
 }
 
 // The length is an unsigned integer preceding the elements.  Even though the length is redundant
 // (it's part of the type), it's a useful check and is included in the encoding.
 func (dec *Decoder) decodeArray(atyp reflect.Type, state *decoderState, value reflect.Value, elemOp decOp, length int, ovfl error) {
-       value = decAlloc(value)
        if n := state.decodeUint(); n != uint64(length) {
                errorf("length mismatch in decodeArray")
        }
 }
 
 // decodeIntoValue is a helper for map decoding.
-func decodeIntoValue(state *decoderState, op decOp, value reflect.Value, ovfl error) reflect.Value {
+func decodeIntoValue(state *decoderState, op decOp, isPtr bool, value reflect.Value, ovfl error) reflect.Value {
        instr := &decInstr{op, 0, nil, ovfl}
-       op(instr, state, value)
+       v := value
+       if isPtr {
+               v = decAlloc(value)
+       }
+       op(instr, state, v)
        return value
 }
 
 // Because the internals of maps are not visible to us, we must
 // use reflection rather than pointer magic.
 func (dec *Decoder) decodeMap(mtyp reflect.Type, state *decoderState, value reflect.Value, keyOp, elemOp decOp, ovfl error) {
-       value = decAlloc(value)
        if value.IsNil() {
                // Allocate map.
                value.Set(reflect.MakeMap(mtyp))
        }
        n := int(state.decodeUint())
+       keyIsPtr := mtyp.Key().Kind() == reflect.Ptr
+       elemIsPtr := mtyp.Elem().Kind() == reflect.Ptr
        for i := 0; i < n; i++ {
-               key := decodeIntoValue(state, keyOp, allocValue(mtyp.Key()), ovfl)
-               elem := decodeIntoValue(state, elemOp, allocValue(mtyp.Elem()), ovfl)
+               key := decodeIntoValue(state, keyOp, keyIsPtr, allocValue(mtyp.Key()), ovfl)
+               elem := decodeIntoValue(state, elemOp, elemIsPtr, allocValue(mtyp.Elem()), ovfl)
                value.SetMapIndex(key, elem)
        }
 }
                // of interfaces, there will be buffer reloads.
                errorf("length of %s is negative (%d bytes)", value.Type(), u)
        }
-       value = decAlloc(value)
        if value.Cap() < n {
                value.Set(reflect.MakeSlice(value.Type(), n, n))
        } else {
        state.b.Read(b)
        name := string(b)
        // Allocate the destination interface value.
-       value = decAlloc(value)
        if name == "" {
                // Copy the nil interface value to the target.
                value.Set(reflect.Zero(value.Type()))
        }
        var op decOp
        op = func(i *decInstr, state *decoderState, value reflect.Value) {
-               value = decAlloc(value)
                // We now have the base type. We need its address if the receiver is a pointer.
                if value.Kind() != reflect.Ptr && rcvrType.Kind() == reflect.Ptr {
                        value = value.Addr()
        if dec.err != nil {
                return
        }
+       value = decAlloc(value)
        engine := *enginePtr
        if st := base; st.Kind() == reflect.Struct && ut.externalDec == 0 {
                if engine.numInstr == 0 && st.NumField() > 0 &&