Search code examples
arrayscfor-loopsizeofconversion-specifier

16bit unsigned int array outputting more elements than initialized size in c


I'm trying to feed data into an array and change only a few values and leaving the rest 0, but I keep receiving much more data than the array should theoretically hold. Here is my code compiled and run with

gcc -o arr arrayconst.c

#include <stdio.h>
#include <stdint.h>
int main(){    
    uint16_t buf_tx[101];
    for(int i = 0; i < sizeof(buf_tx);i++){buf_tx[i]=0;}
    //memset(buf_tx,0,sizeof(buf_tx)*sizeof(uint16_t)); //alternate way of zeroizing
    buf_tx[42] = 0x2000;
    buf_tx[46] = 0x2000;
    buf_tx[48] = 0x2000;
    buf_tx[50] = 0x2000;
    buf_tx[52] = 0x2000;
    buf_tx[54] = 0x2000;
    buf_tx[72] = 0x1000;
    buf_tx[76] = 0x0001;
    for(int i = 0; i < sizeof(buf_tx); i++){
        printf("|%d 0x%04X, ",i,buf_tx[i]);
        
    }
}

and my output:

|0 0x0000, |1 0x0000, |2 0x0000, |3 0x0000, |4 0x0000, |5 0x0000, |6 0x0000, |7 0x0000, |8 0x0000, |9 0x0000, |10 0x0000, |11 0x0000, |12 0x0000, |13 0x0000, |14 0x0000, |15 0x0000, |16 0x0000, |17 0x0000, |18 0x0000, |19 0x0000, |20 0x0000, |21 0x0000, |22 0x0000, |23 0x0000, |24 0x0000, |25 0x0000, |26 0x0000, |27 0x0000, |28 0x0000, |29 0x0000, |30 0x0000, |31 0x0000, |32 0x0000, |33 0x0000, |34 0x0000, |35 0x0000, |36 0x0000, |37 0x0000, |38 0x0000, |39 0x0000, |40 0x0000, |41 0x0000, |42 0x2000, |43 0x0000, |44 0x0000, |45 0x0000, |46 0x2000, |47 0x0000, |48 0x2000, |49 0x0000, |50 0x2000, |51 0x0000, |52 0x2000, |53 0x0000, |54 0x2000, |55 0x0000, |56 0x0000, |57 0x0000, |58 0x0000, |59 0x0000, |60 0x0000, |61 0x0000, |62 0x0000, |63 0x0000, |64 0x0000, |65 0x0000, |66 0x0000, |67 0x0000, |68 0x0000, |69 0x0000, |70 0x0000, |71 0x0000, |72 0x1000, |73 0x0000, |74 0x0000, |75 0x0000, |76 0x0001, |77 0x0000, |78 0x0000, |79 0x0000, |80 0x0000, |81 0x0000, |82 0x0000, |83 0x0000, |84 0x0000, |85 0x0000, |86 0x0000, |87 0x0000, |88 0x0000, |89 0x0000, |90 0x0000, |91 0x0000, |92 0x0000, |93 0x0000, |94 0x0000, |95 0x0000, |96 0x0000, |97 0x0000, |98 0x0000, |99 0x0000, |100 0x0000, |101 0x0000, |102 0x0000, |103 0x0000, |104 0x0000, |105 0x0000, |106 0x0000, |107 0x0000, |108 0x0000, |109 0x0000, |110 0x0000, |111 0x0000, |112 0x0000, |113 0x0000, |114 0x0000, |115 0x0000, |116 0x0000, |117 0x0000, |118 0x0000, |119 0x0000, |120 0x0000, |121 0x0000, |122 0x0000, |123 0x0000, |124 0x0000, |125 0x0000, |126 0x0000, |127 0x0000, |128 0x0000, |129 0x0000, |130 0x0000, |131 0x0000, |132 0x0000, |133 0x0000, |134 0x0000, |135 0x0000, |136 0x0000, |137 0x0000, |138 0x0000, |139 0x0000, |140 0x0000, |141 0x0000, |142 0x0000, |143 0x0000, |144 0x0000, |145 0x0000, |146 0x0000, |147 0x0000, |148 0x0000, |149 0x0000, |150 0x0000, |151 0x0000, |152 0x0000, |153 0x0000, |154 0x0000, |155 0x0000, |156 0x0000, |157 0x0000, |158 0x0000, |159 0x0000, |160 0x0000, |161 0x0000, |162 0x0000, |163 0x0000, |164 0x0000, |165 0x0000, *** stack smashing detected ***: terminated Aborted (core dumped)

any help would be greatly appreciated!


Solution

  • sizeof gives the number of bytes in its operand. In typical C implementations, uint16_t is two bytes, so uint16_t buf_tx[101] is 202 bytes.

    To get the number of elements in an array x, use sizeof x / sizeof *x:

    for (int i = 0; i < sizeof buf_tx / sizeof *buf_tx; i++)
    

    This is often packaged in a macro:

    #define NumberOf(x) (sizeof (x) / sizeof *(x))
    …
    for (int i = 0; i < NumberOf(buf_tx); i++)
    

    This works only for arrays, not for pointers, because sizeof x gives the size of the array if x is an array but the size of the pointer if x is a pointer. Notably, function parameters declared as arrays, such as void foo(int x[]), are automatically adjusted to be pointers, so NumberOf(x) will not work for them.