Question

I have a old program in which some library function is used and i dont have that library.

So I am writing that program using libraries of c++. In that old code some function is there which is called like this

*string = newstrdup("Some string goes here");

the string variable is declared as char **string;

What he may be doing in that function named "newstrdup" ? I tried many things but i dont know what he is doing ... Can anyone help

Was it helpful?

Solution

there has to be a reason that they wrote a "new" version of strdup. So there must be a corner case that it handles differently. like perhaps a null string returns an empty string.

litb's answer is a replacement for strdup, but I would think there is a reason they did what they did.

If you want to use strdup directly, use a define to rename it, rather than write new code.

OTHER TIPS

The function is used to make a copy of c-strings. That's often needed to get a writable version of a string literal. They (string literals) are itself not writable, so such a function copies them into an allocated writable buffer. You can then pass them to functions that modify their argument given, like strtok which writes into the string it has to tokenize.

I think you can come up with something like this, since it is called newstrdup:

char * newstrdup(char const* str) {
    char *c = new char[std::strlen(str) + 1];
    std::strcpy(c, str);
    return c;
}

You would be supposed to free it once done using the string using

delete[] *string;

An alternative way of writing it is using malloc. If the library is old, it may have used that, which C++ inherited from C:

char * newstrdup(char const* str) {
    char *c = (char*) malloc(std::strlen(str) + 1);
    if(c != NULL) {
        std::strcpy(c, str);
    }
    return c;
}

Now, you are supposed to free the string using free when done:

free(*string);

Prefer the first version if you are writing with C++. But if the existing code uses free to deallocate the memory again, use the second version. Beware that the second version returns NULL if no memory is available for dup'ing the string, while the first throws an exception in that case. Another note should be taken about behavior when you pass a NULL argument to your newstrdup. Depending on your library that may be allowed or may be not allowed. So insert appropriate checks into the above functions if necessary. There is a function called strdup available in POSIX systems, but that one allows neither NULL arguments nor does it use the C++ operator new to allocate memory.

Anyway, i've looked with google codesearch for newstrdup functions and found quite a few. Maybe your library is among the results:

Google CodeSearch, newstrdup

The line *string = newstrdup("Some string goes here"); is not showing any weirdness to newstrdup. If string has type char ** then newstrdup is just returning char * as expected. Presumably string was already set to point to a variable of type char * in which the result is to be placed. Otherwise the code is writing through an uninitialized pointer..

newstrdup is probably making a new string that is a duplicate of the passed string; it returns a pointer to the string (which is itself a pointier to the characters).

It looks like he's written a strdup() function to operate on an existing pointer, probably to re-allocate it to a new size and then fill its contents. Likely, he's doing this to re-use the same pointer in a loop where *string is going to change frequently while preventing a leak on every subsequent call to strdup().

I'd probably implement that like string = redup(&string, "new contents") .. but that's just me.

Edit:

Here's a snip of my 'redup' function which might be doing something similar to what you posted, just in a different way:

int redup(char **s1, const char *s2)
{
    size_t len, size;

    if (s2 == NULL)
        return -1;

    len = strlen(s2);
    size = len + 1;

    *s1 = realloc(*s1, size);

    if (*s1 == NULL)
        return -1;

    memset(*s1, 0, size);
    memcpy(*s1, s2, len);

    return len;
}

Of course, I should probably save a copy of *s1 and restore it if realloc() fails, but I didn't need to get that paranoid.

I think you need to look at what is happening with the "string" variable within the code as the prototype for the newstrdup() function would appear to be identical to the library strdup() version.

Are there any free(*string) calls in the code?

It would appear to be a strange thing do to, unless it's internally keeping a copy of the duplicated string and returning a pointer back to the same string again.

Again, I would ask why?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top