简体   繁体   中英

Copying C-Style String to Free Store Using Only Dereference

As said in the title, the goal is to copy a C-style string into memory without using any standard library functions or subscripting.

Here is what I have so far [SOLVED]

#include "std_lib_facilities.h"

char* strdup(const char* p)
{
    int count = 0;
    while (p[count]) ++count;
    char* q = new char[count+1];
    for (int i = 0; i < count + 1; ++i) *(q + i) = *(p + i);
}

int main()
{
    char word[] = "Happy";

    char* heap_str = strdup(word);
}

Obviously the problem is that allocating just *p (which is equivalent to p[0] ) only allocates the letter "H" to memory. I'm not sure how to go about allocating the C-style string without subscripting or STL functions.

C-style string ends with '\\0'. You need to traverse the string inside the function character by character until you encounter '\\0' to know how long it is. (This is effectively what you would do by calling strlen() to work it out.) Once you know how long the string is, you can allocate the right amount of memory, which is the length+1 (because of the '\\0').

To access the i'th element of an array p, one use subscript: p[i] .

Subscript of the form p[i] is formally defined to be *((p)+(i)) by both the C standard (6.5.2.1 of C99) and the C++ standard (5.2.1 of C99). Here, one of p or i is of the type pointer to T, and the other is of integral type (or enumeration in C++). Because array name is converted automatically (in most types of use anyway) to a pointer to the first element of said array, p[i] is thus the i'th element of array p.

And just like basic arithmetic, ((p)+(i)) is equivalent to ((i)+(p)) in pointer arithmetic. This mean *((p)+(i)) is equivalent to *((i)+(p)) . Which also mean p[i] is equivalent to i[p] .

Well, since this a self-teaching exercise, here's an alternative look at a solution that can be compared/contrasted with KTC's nice explanation of the equivalence between subscripting and pointer arithmetic.

The problem appears to be, "implement a strdup() function without using standard library facilities or subscripting".

I'm going to make an exception for malloc() , as there's no reasonable way to do the above without it, and I think that using it isn't detrimental to what's being taught.

First, let's do a basic implementation of strdup() , calling functions that are similar to the ones we might use from the library:

size_t myStrlen( char* s);
void myStrcpy( char* dst, char* src);

char* strdup( char* p)
{
    size_t len = myStrlen( p);

    char* dup = (char*) malloc( len + 1);   /* include space for the termination character */

    if (dup) {
        myStrcpy( dup, p);
    }

    return dup;
}

Now lets implement the worker functions without subscripting:

size_t myStrlen( char* s)
{
    size_t len = 0;

    while (*s != '\0') {  /* when s points to a '\0' character, we're at the end of the string */
        len += 1;

        s += 1; /* move the pointer to the next character */
    }

    return len;
}


void myStrcpy( char* dst, char* src)
{
    while (*src != '\0') {  /* when src points to a '\0' character, we're at the end of the string */
        *dst = *src;

        ++dst;  /* move both pointers to next character location */
        ++src;
    }

    *dst = '\0'; /* make sure the destination string is properly terminated */
}

And there you have it. I think this satisfies the condition of the assignment and shows how pointers can be manipulated to move though an array of data items instead of using subscripting. Of course, the logic for the myStrlen() and myStrcpy() routines can be moved inline if desired, and more idiomatic expressions where the pointer increment can happen in the expression that copies the data can be used (but I think that's more confusing for beginners).

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