简体   繁体   中英

How to add null terminator to char pointer, when using strcpy

I have a program that's attempting to use the strcpy() function. I know that when one uses a char array such as: char array[10] the null terminator can be set by: array[0] = '\\0'; However, how would I go about setting the null terminator(s) when using char pointers?

EDIT: The program compiles, but gives garbage as output

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

int main(void)
{
    char *target;
    char *src = "Test";

    target = malloc(sizeof(char));
    src = malloc(sizeof(char));

     strcpy(target,src);
     printf("%c\n",target); 

    return 0;
}

You don't need to. Second argument of strcpy() needs to be nul terminated, and the first needs to fit the number of characters in source + the nul terminator.

The problems in your code are:

  1. You are using sizeof operator in wrong way and you are overwriting the src pointer by allocating memory again to it.

    To get the length of a string you need strlen() and you don't need to call malloc() on every pointer.

    You are getting garbage value because you are copying from uninitialized data since src points to a newly allocated space, because of

     src = malloc(sizeof(char)); 

    you should not do that.

  2. sizeof(char) == 1 by definition, so you are allocating space for just 1 byte, which if it was to be a valid C string, has to be '\\0' because there is room for just 1 character.

  3. The correct printf() specifier for a string is "%s" , you are using "%c" which is for a character.

The correct way to do it is

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

int main(void)
{
    char       *target;
    const char *src;

    src    = "Test"; /* point to a static string literal */
    target = malloc(1 + strlen(src)); /* allocate space for the copy of the string */
    if (target == NULL) /* check that nothing special happened to prevent tragedy  */
        return -1;

    strcpy(target, src);
    printf("%s\n", target);
    /* don't forget to free the malloced pointer */
    free(target);

    return 0;
}

In your code

strcpy(target,src);

src is not null-terminated. This invokes undefined behaviour.

Also, by using malloc(sizeof(char)); you're allocating memory for ony a single char element. which is probably you don't want.

Next, as per the man page of strcpy() , (emphasis mine)

The strcpy() function copies the string pointed to by src , including the terminating null byte ( '\\0' ) to the buffer pointed to by dest . The strings may not overlap, and the destination string dest must be large enough to receive the copy .

so, as long as

  1. your source is a proper null-terminated char array ( string )
  2. destination is having enough memory to hold the containts of source

you're good to go. So, you've to

  1. null-terminate the src array.
  2. allocate enough memory to target so that it can hold the contains of src .

Lastly, to mention, once you've used a string, you're supposed to use the %s format specifier with printf() to print the string.

target = malloc(10);

Have memory to accommodate the string and a nul terminator. I don't get why you are allocating memory for src as I see you are using a string literal. Just allocate enough memory for destination and do strcpy() make sure you are not writing to array out of bound.

The right way would be to

target = malloc((strlen(src) + 1));

Make a note that when you do

char *src = "Test";

The string "Test" is stored in a read-only location and the address of this location is returned to src . So your string is already in memory and no need to allocate memory for this again which you are trying to do and doing it wrongly. So get rid of malloc() for src

man strcpy

DESCRIPTION
The strcpy() function copies the string pointed to by src, including the terminating null byte ('\\0'), to the buffer pointed to by dest.

So you don't have to add null-terminate byte if src has it already.

BUGS
If the destination string of a strcpy() is not large enough, then anything might happen.

So :

char *src = "Test"; //  4 chars + '\0'
target = malloc(sizeof(char)); // Space for 1 char
 strcpy(target,src); // Woops !

Answers thus far have addressed the flaws in your code and your apparent misunderstanding rather than your question. Pointers to memory can be indexed just like arrays, so given:

char *target = malloc( 10 ) ;

One can set elements thus:

target[0] = '\0' ;

Sourav Ghosh's answer is correct, but for this specific case you should use strdup() as it handles both memory allocation and copying for you:

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

int main(void)
{
    const char *src = "Test";   // You should make this const
    char *target = strdup(src); // Duplicate             
    if (target == NULL) {       // Check
        return EXIT_FAILURE;
    }
    printf("%s\n", target);
    return EXIT_SUCCESS;
}   

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM