-2
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void main()
{
    unsigned char str[] = "abcdefg";
    unsigned char *str1 = (unsigned char*)malloc(sizeof(str) -1);

    memcpy(str1, str, (sizeof(str)-1) );

    for(int i = 0; i<(sizeof(str1)); i++)
        printf("%c", str1[i]);

    free(str1);
}

I want copy the string str to str1 but the output is

abcd

It means that only pointer byte(4byte) is copied.

And i try

printf("%d", sizeof(str)-1 );

it's output is 7

What is my mistake?

klutt
  • 30,332
  • 17
  • 55
  • 95
sang oh
  • 66
  • 1
  • 8

3 Answers3

1

it mean that only pointer byte(4byte) is copied.

No, it does not. You're assuming that your printout is correct, which it is not. You can use sizeof on arrays but not on pointers. Well, you can, but it means something different.

Everything is copied. You're just printing the first four characters. Change to:

for(int i = 0; i<(sizeof(str) - 1); i++)

Also, don't cast malloc. Here is why: Do I cast the result of malloc?

klutt
  • 30,332
  • 17
  • 55
  • 95
1

str1 is a pointer whereas str is a character array. When you say sizeof(str1) in your for loop, it iterates 4 times because sizeof(str1) must have evaluated to 4(a 32 bit compiler) whereas sizeof(str) evaluates to the correct length.

You should read What is the size of a pointer? once to know more about size of pointers.

Fixed code:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void main()
{
    unsigned char str[] = "abcdefg";
    unsigned char *str1 = (unsigned char*)malloc(sizeof(str) -1);

    memcpy(str1, str, (sizeof(str)-1) );

    for(int i = 0; i<(sizeof(str) - 1); i++)
        printf("%c", str1[i]);

    free(str1);
}
Mihir Luthra
  • 6,059
  • 3
  • 14
  • 39
1

First the mistakes and then the correct code: Mistakes:

  1. Don't ever use sizeof(str) to get the length of the string. It doesn't work with pointers. Instead, use strlen(str) + 1.
  2. You are subtracting 1 from the size of the string on malloc call. Why? You are not making space for the ending NULL character.
  3. When copying strings, if you know that the destination string is large enough to store the source, use strcpy instead of memcpy. If you only want an additional size parameter like in memcpy, use strncpy. memcpy is not meant to deal with strings, but with plain arrays.
  4. The correct type to use for strings is char, not unsigned char.
  5. Not really a mistake, but to print a string you can use printf("%s", str) or puts(str). Why bother with a for loop?
  6. void main() is prohibited by the C standard.

Correct code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    char str[] = "abcdefg";
    char str1* = malloc(strlen(str) + 1);
    strcpy(str1, str);
    puts(str1);
    free(str1);
    //return 0; - default in C99 and later
}
DarkAtom
  • 2,589
  • 1
  • 11
  • 27