Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: How to use new to find store for function return value?

Tags:

c++

I'm reading the 3rd edition of The C++ Programming Language by Bjarne Stroustrup and attempting to complete all the exercises. I'm not sure how to approach exercise 13 from section 6.6, so I thought I'd turn to Stack Overflow for some insight. Here's the description of the problem:

Write a function cat() that takes two C-style string arguments and returns a single string that is the concatenation of the arguments. Use new to find store for the result.

Here's my code thus far, with question marks where I'm not sure what to do:

? cat(char first[], char second[])
{
    char current = '';
    int i = 0;

    while (current != '\0')
    {
        current = first[i];
        // somehow append current to whatever will eventually be returned
        i++;
    }

    current = '';
    i = 0;

    while (current != '\0')
    {
        current = second[i];
        // somehow append current to whatever will eventually be returned
        i++;
    }

    return ?
}

int main(int argc, char* argv[])
{
    char first[]  = "Hello, ";
    char second[] = "World!";

    ? = cat(first, second);

    return 0;
}

And here are my questions:

  1. How do I use new to find store? Am I expected to do something like std::string* result = new std::string; or should I be using new to create another C-style string somehow?
  2. Related to the previous question, what should I return from cat()? I assume it will need to be a pointer if I must use new. But a pointer to what?
  3. Although the problem doesn't mention using delete to free memory, I know I should because I will have used new to allocate. Should I just delete at the end of main, right before returning?
like image 578
Rob Johansen Avatar asked Jul 27 '13 23:07

Rob Johansen


4 Answers

How do I use new to find store? Am I expected to do something like std::string* result = new std::string; or should I be using new to create another C-style string somehow?

The latter; the method takes C-style strings and nothing in the text suggests that it should return anything else. The prototype of the function should thus be char* cat(char const*, char const*). Of course this is not how you’d normally write functions; manual memory management is completely taboo in modern C++ because it’s so error-prone.

Although the problem doesn't mention using delete to free memory, I know I should because I will have used new to allocate. Should I just delete at the end of main, right before returning?

In this exercise, yes. In the real world, no: like I said above, this is completely taboo. In reality you would return a std::string and not allocate memory using new. If you find yourself manually allocating memory (and assuming it’s for good reason), you’d put that memory not in a raw pointer but a smart pointer – std::unique_ptr or std::shared_ptr.

like image 168
Konrad Rudolph Avatar answered Oct 22 '22 19:10

Konrad Rudolph


In a "real" program, yes, you would use std::string. It sounds like this example wants you to use a C string instead.

So maybe something like this:

char * cat(char first[], char second[])
{
    char *result = new char[strlen(first) + strlen(second) + 1];

...

Q: How do you "append"?

A: Just write everything in "first" to "result".

As soon as you're done, then continue by writing everything in "second" to result (starting where you left off). When you're done, make sure to append '\0' at the end.

like image 43
paulsm4 Avatar answered Oct 22 '22 20:10

paulsm4


  1. You are supposed to return a C style string, so you can't use std::string (or at least, that's not "in the spirit of the question"). Yes, you should use new to make a C-style string.
  2. You should return the C-style string you generated... So, the pointer to the first character of your newly created string.
  3. Correct, you should delete the result at the end. I expect it may be ignored, as in this particular case, it probably doesn't matter that much - but for completeness/correctness, you should.
like image 32
Mats Petersson Avatar answered Oct 22 '22 19:10

Mats Petersson


Here's some old code I dug up from a project of mine a while back:

char* mergeChar(char* text1, char* text2){
    //Find the length of the first text
    int alen = 0;
    while(text1[alen] != '\0')
        alen++;

    //Find the length of the second text
    int blen = 0;
    while(text2[blen] != '\0')
        blen++;

    //Copy the first text
    char* newchar = new char[alen + blen + 1];
    for(int a = 0; a < alen; a++){
            newchar[a] = text1[a];
    }

    //Copy the second text
    for(int b = 0; b < blen; b++)
        newchar[alen + b] = text2[b];

    //Null terminate!
    newchar[alen + blen] = '\0';
    return newchar;
}

Generally, in a 'real' program, you'll be expected to use std::string, though. Make sure you delete[] newchar later!

like image 31
BrainSteel Avatar answered Oct 22 '22 18:10

BrainSteel