Skip to content

Latest commit

 

History

History

Chapter12

Chapter12: Dynamic Memory

How many elements do b1 and b2 have at the end of this code?

StrBlob b1;
{
    StrBlob b2 = {"a", "an", "the"};
    b1 = b2;
    b2.push_back("about");
}

Write your own version of the StrBlob class including the const ver- sions of front and back.

Does this class need const versions of push_back and pop_back? If so, add them. If not, why aren’t they needed?

In our check function we didn’t check whether i was greater than zero. Why is it okay to omit that check?

We did not make the constructor that takes an initializer_list explicit (§ 7.5.4, p. 296). Discuss the pros and cons of this design choice.

Write a function that returns a dynamically allocated vector of ints. Pass that vector to another function that reads the standard input to give values to the elements. Pass the vector to another function to print the values that were read. Remember to delete the vector at the appropriate time.

Redo the previous exercise, this time using shared_ptr.

Explain what if anything is wrong with the following function.

bool b() {
    int* p = new int;
    // . . .
    return p;
}

Explain what happens in the following code:

int *q = new int(42), *r = new int(100);
r = q;
auto q2 = make_shared<int>(42), r2 = make_shared<int>(100);
r2 = q2;

Explain whether the following call to the process function defined on page 464 is correct. If not, how would you correct the call?

shared_ptr<int> p(new int(42));
process(shared_ptr<int>(p));

What would happen if we called process as follows?

process(shared_ptr<int>(p.get()));

Using the declarations of p and sp explain each of the following calls to process. If the call is legal, explain what it does. If the call is illegal, explain why:

auto p = new int();
auto sp = make_shared<int>();
(a) process(sp);
(b) process(new int());
(c) process(p);
(d) process(shared_ptr<int>(p));

What happens if we execute the following code?

auto sp = make_shared<int>();
auto p = sp.get();
delete p;

Write your own version of a function that uses a shared_ptr to man- age a connection.

Rewrite the first exercise to use a lambda (§ 10.3.2, p. 388) in place of the end_connection function.

Compilers don’t always give easy-to-understand error messages if we attempt to copy or assign a unique_ptr. Write a program that contains these errors to see how your compiler diagnoses them.

Which of the following unique_ptr declarations are illegal or likely to result in subsequent program error? Explain what the problem is with each one.

int ix = 1024, *pi = &ix, *pi2 = new int(2048);
typedef unique_ptr<int> IntP;
(a) IntP p0(ix);
(b) IntP p1(pi);
(c) IntP p2(pi2);
(d) IntP p3(&ix);
(e) IntP p4(new int(2048));
(f) IntP p5(p2.get());

Why doesn’t shared_ptr have a release member?

Define your own version of StrBlobPtr and update your StrBlob class with the appropriate friend declaration and begin and end members.

Write a program that reads an input file a line at a time into a StrBlob and uses a StrBlobPtr to print each element in that StrBlob.

We could have written StrBlobPtr’s deref member as follows:

std::string& deref() const
{ return (*check(curr, "dereference past end"))[curr]; }

Which version do you think is better and why?

What changes would need to be made to StrBlobPtr to create a class that can be used with a const StrBlob? Define a class named ConstStrBlobPtr that can point to a const StrBlob.

Write a program to concatenate two string literals, putting the result in a dynamically allocated array of char. Write a program to concatenate two library strings that have the same value as the literals used in the first program.

Write a program that reads a string from the standard input into a dynamically allocated character array. Describe how your program handles varying size inputs. Test your program by giving it a string of data that is longer than the array size you’ve allocated.

Given the following new expression, how would you delete pa?

int *pa = new int[10];

Rewrite the program on page 481 using an allocator.

The TextQuery and QueryResult classes use only capabilities that we have already covered. Without looking ahead, write your own versions of these classes.

Write a program to implement text queries without defining classes to manage the data. Your program should take a file and interact with a user to query for words in that file. Use vector, map, and set containers to hold the data for the file and to generate the results for the queries.

We could have written the loop to manage the interaction with the user as a do while (§ 5.4.4, p. 189) loop. Rewrite the loop to use a do while. Explain which version you prefer and why.

Define your own versions of the TextQuery and QueryResult classes and execute the runQueries function from § 12.3.1 (p. 486).

What difference(s) would it make if we used a vector instead of a set to hold the line numbers? Which approach is better? Why?

Rewrite the TextQuery and QueryResult classes to use a StrBlob instead of a vector to hold the input file.

In Chapter 15 we’ll extend our query system and will need some addi- tional members in the QueryResult class. Add members named begin and end that return iterators into the set of line numbers returned by a given query, and a member named get_file that returns a shared_ptr to the file in the QueryResult object.