1

I have a function

static void writeBytes(char ** pDestStr, char* item) {
  int size=strlen(item); // expected size==2
  memcpy(*pDestStr,item,size);
  *pDestStr+=size;
}

and a 2 byte string defined in struct HEADER

typedef struct HEADER {
  unsigned char magicNo[2]; // two bytes
} BMPHEADER;

In my program the magicNo is set to 2 bytes and it contains "BM". But when I call the function like this:

writeBytes(&pBlock, bmpfile->header.magicNo);

inside writeBytes there is sizeof item == 4 bytes and sizeof *item == 1 byte, hence I ask, why this happen? The string contains 2 additional characters which I did not set. This is on the first line of the function definition. As a result the function works wrong because it adds the pointer +4 instead +2 bytes... Any idea how to fix this?

Solved: Answered in comments. Correct size of magicNo should be 3 and I am missing terminating character \0. So correction:

unsigned char magicNo[3];
John Boe
  • 3,501
  • 10
  • 37
  • 71
  • Can you show what's "inside it"? It could happen that you mistake the size of a pointer with the size of a datatype – Vinz Feb 18 '15 at 12:03
  • 2
    possible duplicate of [How to find the 'sizeof'(a pointer pointing to an array)?](http://stackoverflow.com/questions/492384/how-to-find-the-sizeofa-pointer-pointing-to-an-array) – Klas Lindbäck Feb 18 '15 at 12:04
  • @user3121023: if you post it as an answer I will accept it. Thanks. – John Boe Feb 18 '15 at 12:13
  • Are **you** defining those headers or are you trying to read existing files? The official BMP header does has `char[2]` as the 1st two bytes: http://en.wikipedia.org/wiki/BMP_file_format#Bitmap_file_header so defining `char[3]` won't help you. – alk Feb 18 '15 at 13:07

2 Answers2

3

A string literal in C is terminated by null char i.e. \0

Thus "BM" is actually B,M,0 stored at consecutive locations.

strlen() evaluates the passed char * till it finds the '\0' char.

As your magicNo[2] array is of two bytes only it does not hold the null char,strlen() is searching for null in your case and luckily null is found at 5th location from start of array that's why you are getting wrong string length.

Notes:

sizeof(magicNo); --> Gives size of `magicNo` array.
sizeof(item); --> Gives size of character pointer 
sizeof(*item); --> Gives size of single character

EDIT: In your example code:

int size=strlen(item); // expected size==2

You are assuming wrong here,strlen do NOT gives the size of array. If you want to find the size of array based on passed pointer to it then you CAN'T do that in C. You have to remember it explicitly in code.

Vagish
  • 2,520
  • 19
  • 32
  • 2
    `unsigned char magicNo[2]` can store only `'B'` and `'M'`, there is no space for `'\0'` – HolyBlackCat Feb 18 '15 at 12:08
  • There's no necessity for `magicNo` to be a *string* despite what OP accepting this. It could very well be a 2 byte array with length being passed , especially looking at `writeBytes()` definition and and it's simply a memcpy. – P.P Feb 18 '15 at 12:33
  • @BlueMoon that is what my answer is, to get size of a array you cannot use `strlen()`. we are talking the same thing here. – Vagish Feb 18 '15 at 12:42
2

Inside the function, when you do sizeof item, it returns the size of the char pointer i.e. sizeof(char*), not the number of bytes it's pointing to.

P.P
  • 117,907
  • 20
  • 175
  • 238
  • 2
    He is not doing `sizeof` anywhere in code this is irrelevant here. – Vagish Feb 18 '15 at 12:11
  • 2
    @Vagish Look at OP's post: `inside writeBytes there is sizeof item == 4 bytes and sizeof *item == 1 byte, hence I ask, why this happen?` – HolyBlackCat Feb 18 '15 at 12:13
  • @Vagish Read the question properly before dictating what's relevant or irrelevant. – P.P Feb 18 '15 at 12:29
  • @BlueMoon sorry,the OP has not formatted sizeof into code format so I took its literal meaning. – Vagish Feb 18 '15 at 12:40