3

How to copy use memcpy with two pointers a, b both are unsigned char *:

  1. a pointing to memory filled with data (unsigned char)
  2. b is even not allocated

How to copy a to b using memcpy? The third parameter of memcpy needs the size of the memory pointed to by a in bytes; how to get it?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
user1051003
  • 1,211
  • 5
  • 16
  • 24
  • 2
    Summary: you can't "get" the length. Whoever filled `a` with data needs to tell you the length. That could be by passing you the number of bytes, or it could be by ensuring that the data in `a` is structured in some way that lets you work out the length by reading part or all of the data (e.g. NUL-terminated, contains a length field). – Steve Jessop Sep 01 '12 at 17:59

3 Answers3

5
unsigned char* b = (unsigned char*)malloc(length_of_a);
memcpy(b, a, length_of_a);

Of course, I can't tell you how to get the length of "a". You can't reliably call memcpy If you don't know it or don't have it as a variable. Otherwise, any attempt to call memcpy is inherently unsafe.

What are you really trying to do?

It's also entirely possible that "a" is not an array at all. In which case you don't need memcpy:

char b = '\0';
if (a != NULL)
{
    b = *a;
}
selbie
  • 100,020
  • 15
  • 103
  • 173
  • It was clearly mentioned that 'a' is 'unsigned char *'. OP never said 'a' is 'array'. Also '*a' gives only the first character. I don't know what you wanted to achieve using the above code. Please review. Thanks. – Ayub Sep 01 '12 at 17:01
  • 1
    @Ayub - the OP's question is ambiguous at best. Hence, my answer can only be comprised of hints. I'm not sure what you disagree with, but perhaps you missed the pair of malloc/memcpy statements at the top of this answer as one possible solution. The other solution is the b=*a case for when "a" is not an array at all. – selbie Sep 01 '12 at 17:09
3

We must assume that a is NUL terminated (ending with '\0'), otherwise we can't be sure about its size/length (unless you know the length of a yourself).

char *a = "Hello World"; /* say for example */
size_t len = strlen(a)+1; /* get the length of a (+1 for terminating NUL ('\0') character) */

Note that, if you know the length of the string pointed to by (or saved in) a then you will assign it to len, instead of using the above statement.

char *b = calloc(1, len); /* */
memcpy(b, a, len); /* now b contains copy of a */

If your intention is just to make a copy of a string (NUL terminated), you can use strdup() (declared in string.h):

char *b = strdup(a); /* b now has a copy of a */

NOTE: strdup() is in POSIX. If you want strict ANSI C then you can make a wrapper like following as I mentioned earlier:

unsigned char *my_strdup(const unsigned char *a)
{
  size_t len = strlen(a)+1;
  unsigned char *b = calloc(1, len);
  if (b) return (unsigned char *) memcpy(b, a, len);
  return NULL; /* if calloc fails */
}
Community
  • 1
  • 1
Ayub
  • 989
  • 10
  • 12
  • 1
    Two points. 1) calloc is less efficient than malloc. calloc will initialize every byte in the array to 0. And then your memcpy will overwrite every byte anyway. 2) Without knowing more details from the OP, you can't assume that the data is a string, especially if it's declared as unsigned char*. That typically, but not always, implies an array of binary data. – selbie Sep 01 '12 at 17:16
  • The OP asked for using 'memcpy'. The OP himself doesn't know the way of getting length. One way of getting length of (hopefully NUL-terminated) string is strlen(). The OP asked as last 'how' to get the length. Without knowing the length of binary data it's impossible to copy it to another location, as you know. – Ayub Sep 01 '12 at 17:44
  • FYI: http://stackoverflow.com/questions/2688466/why-mallocmemset-slower-than-calloc – Ayub Sep 01 '12 at 17:54
1

Assuming "a" is null terminated, you should be able to use strlenb(a) to get its length, use calloc to allocate the memory for the destination pointer, then use memcpy as you noted.

David W
  • 10,062
  • 34
  • 60