-1

i would like to know if strdup adds a '\0' at the end of the new array if the src array does not contain one ?

let's assume we have an array containing "hello" allocated by this kind of malloc

malloc(sizeof(char) * 5);

so 5 bytes for 5 characters.

I guess the src string did not received the sufficient memory for the '\0'.

What is supposed to happen in this case ?

Anthony
  • 185
  • 1
  • 14
  • 6
    How can the source string not contain one? – John3136 Apr 16 '15 at 00:29
  • If you're giving a pure string for example, like "hello" ? – Anthony Apr 16 '15 at 00:33
  • 4
    Yep. `"hello"` contains a `\0`. – John3136 Apr 16 '15 at 00:34
  • I didn't know about that, but if you initializing wrong your char*, I mean. Malloc him for 6 byte and giving to him 6 char... something like that. I know the compilateur will try to add a \0 but it can fail Am I wrong ? – Anthony Apr 16 '15 at 00:38
  • `strdup()` will allocate the right amount of memory for you, but if you do `dest = malloc(4); strcpy(dest, "1234");` result is undefined behavior since `strcpy` writes 5 bytes (it adds the `\0`) into your 4 bytes of space. – John3136 Apr 16 '15 at 00:43
  • @Anthony: If your string isn't a null-terminated array of `char` then you shouldn't pass it to library functions that assume they will receive a valid C-style string. – Blastfurnace Apr 16 '15 at 00:49
  • All C strings are terminated by a \0. Then all C strings use one byte more the text inside them! – Sir Jo Black Apr 16 '15 at 00:51
  • 1
    @Blastfurnace if your array of char is not null-terminated then you shouldn't be using the word "string". – William Pursell Apr 16 '15 at 01:04
  • @WilliamPursell: You're right. Of course there are other string representations such as length-prefixed Pascal strings but this is a C library function question. – Blastfurnace Apr 16 '15 at 01:37
  • "... if the src string does not contain one ?" is a contradiction. "A string is a contiguous sequence of characters terminated by and including the first `null` character." C11 A string, by definition, contains ` 1 and only 1 null character. Otherwise it is just an array of characters. – chux - Reinstate Monica Apr 16 '15 at 02:07
  • My compiler's implementation of `strdup` (actually `strndupa`) was dropping the terminating null character. I had to implement my own function. Too bad, too; I liked how it put the duplicated string on the stack. – Jim Fell Jun 17 '21 at 22:45

2 Answers2

4

First the standard disclaimer: strdup isn't a standardized function, so exactly what it does could (at least in theory) vary from one compiler to the next. That said, every implementation I've seen of it has worked the same way.

strdup will determine the length of the input string--it'll start from the address in the pointer you pass, and find the first NUL byte after that location. Then it'll allocate a new block of memory and copy the bytes in that range to the newly allocated block.

So one of two things will happen. Either the input will contain a zero byte, and the result will too, or else strdup will read past the end of the input you passed, and you'll get undefined behavior (but chances are pretty good it'll find a zero byte eventually, and copy a bunch of extra garbage to the duplicate string).

One other minor note: if you use strdup, and then try to port you code to a compiler that doesn't define it, you might consider writing your own:

char *strdup(char const *s) { 
    size_t len = strlen(s) + 1;
    char *ret = malloc(len);
    if (ret != NULL)
        strcpy(ret, s);
    return ret;
}

That's obviously a pretty easy thing to do, but it has one other problem: including it in your code produces undefined behavior. You're not allowed to write a function with a name that starts with str. Those are all reserved for the implementation. So even though the function is simple and the behavior of its content is perfectly well defined, the mere existence of the function as a whole still gives undefined behavior.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
0

What strdup() will do in this case is start with the string passed, and go on looking through memory until it either falls off the end of allocated memory (and you get a SIGSEGV or similar) or finds a byte that happens to contain a '\0'.

It will allocate enough memory to include a copy of everything it scanned, including the '\0', and then copy everything.

Arlie Stephens
  • 1,146
  • 6
  • 20
  • Note that if the string passed to strdup() is e.g. a compile time constant, as in strdup("This is my string"), the string _will_ end with '\0 and this case won't apply. – Arlie Stephens Apr 16 '15 at 00:36