0

I can't seem to figure out what is wrong with my code below:

I have a double pointer char array, declared and initialized with the following:

unsigned char **buffer = (unsigned char**) malloc (num * sizeof(char*));
for ( i = 0; i < num; i++ )
{
    buffer[i] = (unsigned char*) calloc(PACKETSIZE, sizeof(char));
}

Then I'm trying to copy a string to the middle section of one of the char* arrays, but it does not seem to work. I'm not sure whether my error was with the memory allocation or when I tried to copy. I know for a fact the source char* has content.

The code I'm trying to copy (Header is a struct, I want to write to the array after the memory address of Header for buffer[i], so I'm doing a bit of a pointer arithmetic).

 strncpy ((unsigned char *)(buffer[i]+sizeof(Header)), buffer2, bytes_to_copy);

After the code runs, the buffer[i] stays empty.

Here is a sample of the Header struct:

typedef struct Head
{
    unsigned int x; 
    unsigned int y; 
} Header ;
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
Tim Z
  • 3
  • 4
  • General hint: `strncpy` is not the somewhat safer version of `strcpy`. Read the documentation closely. – Jabberwocky Nov 06 '20 at 09:13
  • So what's the relation between PACKETSIZE and `sizeof(Header)`? This smells like a plain out of bounds access. Do these things in several steps, store `buffer[i]+sizeof(Header)` in a tmp variable and watch it in your debugger. Does it make sense? Also, always suspect the dangerous `strncpy` function, does it actually null terminate the string in this case? Use the safer `strcpy` or `memcpy` instead, if possible. – Lundin Nov 06 '20 at 09:14
  • 1
    Also... if you calloc `buffer[i]` it's all zeroes. If you then write to `buffer[i] + whatever`, then `buffer[i]` will still contain zero. So what do you mean "empty"? There is a null terminator in the beginning of the string `buffer[i]`, as per your program design. – Lundin Nov 06 '20 at 09:17
  • So my issue seems to be a combination of both you and Adrian's answer below. For my strncpy, i initially forgot to add the Null char to terminate my buffer. However, after I fixed it, using strcpy, My debugger statements were still not outputting anything when i thought it was still not working, but this was due to my header having small unsigned int values, which, when having 0s in a byte, act like a null char for my debug statement so the packet appeared empty but it was really not. Thank you everyone! – Tim Z Nov 06 '20 at 09:39
  • really appreciate everyone's help! Been stuck on this for the whole night. – Tim Z Nov 06 '20 at 09:42

1 Answers1

1

Your allocation line:

    buffer[i] = (unsigned char*) calloc(PACKETSIZE, sizeof(char));

will set all elements of buffer[i] to zero.

Then, your copy line:

    strncpy ((unsigned char *)(buffer[i]+sizeof(Header)), buffer2, bytes_to_copy);

will only set the buffer[i] data that come after the first sizeof(Header) elements.

So, those first sizeof(Header) elements will be zero. Thus, any attempt to use a strxxx function to display that buffer will assume the string is empty (first byte is zero).

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • Actually sorry i forgot to mention I did set values to the header already. – Tim Z Nov 06 '20 at 09:25
  • @TimZ But what did you set them *to*? Chances are, if the first `int` of the header structure is something like `7`, then the first *byte* of that will *still* be zero. If you want to use character-string functions to count or print the data, you need to pass `buffer[i]+sizeof(header)` to *each of those functions*. – Adrian Mole Nov 06 '20 at 09:26
  • that's true!! i think that's why my debugger (printf) isn't working since i'm trying to print %s. is there a way for me to print the whole char array for the entire length that was allocated regardless of 0s? – Tim Z Nov 06 '20 at 09:33
  • @TimZ My suggestion is to not use string storage for data that is not string data. Maybe make a `struct` that has your header's `x` and `y` elements *plus* a `char*` data pointer? – Adrian Mole Nov 06 '20 at 09:37
  • unfortunately that is not possible :( i'm trying to send the packet through a socket call. But anyways, i think my issue is resolved, thanks! ALso I figured out to output the correct data section of the string, i can just use pointer arithmetic again. – Tim Z Nov 06 '20 at 09:41