While using splice and slice in array from where to start cout on string i am little bit confuse about it? - slice

While using splice and slice in array from where to start cout on
string i am little bit confuse about it?
ex:
`const array=["mango","orange","pineapple","watermelon"];
for splice or slice method from where should start count ?

Related

In the following example, from where does the pointer p gets the information?

vector& vector::operator = (const vector& a)
//make this vector a copy of a
{
double* p = new double [ a.sz ]; // allocate new space
copy(a.elem, a.elem+a.sz, elem); // copy elements
delete[] elem; // deallocate old space
elem = p; // now we can reset elem
sz = a.sz;
return *this; // return a self-reference
}
I thought that the third argument of std::copy() should be the pointer p, but the book (Programming principles and practice using C++ - 2nd edition) says:
"When implementing the assignment, you could consider simplifying the code by freeing the memory for the old elements before creating the copy, but it is usually a very good idea not to throw away information before you know that you can replace it. Also, if you did that, strange things would happen if you assigned a vector to itself" - Page 635 and 636.
So, the pointer elem must be third argument of std::copy() to not let the pointer be invalid for a moment. I think...
But from where does p gets the information to be put in the array it points to, to be able to do: elem = p ?
I already know copy and swap strategy exist, you don't have to explain that.
I want to comprehend what is above.
No, that is a typo.
std::copy(a.elem, a.elem+a.sz, p);
is what the code should read.

`std::forward_list` walk until iterator is null?

Is it possible to walk a std::forward_list, incrementing an iterator, until said interator is null? The old-fashioned way...
In the following example, I create a print() function.
#include <iostream>
#include <forward_list>
void print(std::forward_list<int>::iterator fl_it, std::forward_list<int>::iterator e) {
while (fl_it != e) {
std::cout << *fl_it << ' ';
++fl_it;
}
std::cout << std::endl; //-> 1 2 3
}
int main() {
std::forward_list<int> fl = {1, 2, 3};
print(fl.begin(), fl.end());
std::cout << std::endl;
return 0;
}
Notice how passing an iterator pointing to the end of the list is necessary, so that we know when to stop walking.
What I want to do is simply pass an iterator to the head of the list, and step along until there are no more elements, like so:
void print(std::forward_list<int>::iterator fl_it) {
while (fl_it != nullptr) {
std::cout << *fl_it << ' ';
++fl_it;
}
std::cout << std::endl;
}
My compiler doesn't like this fl_it != nullptr business.
My first inclination was to look for a method to check if the iterator is null, and references the end of the list. Sadly, such a method does not exist.
Any ideas?
You don't.
std::forward_list is a standard library container. Like all containers, it goes from begin to end. There are no "null" iterators. Operations therefore are on a range of iterators.
Note that the Range TS proposal intends to allow "sentinel" types instead of requiring end iterators. A single sentinel could compare equal to the end iterator of any range. So forward_list could indeed be updated to have such a value.
But it still wouldn't be a "null" iterator.
You should realise that the iterator object is not exactly a pointer. It is an object and it represents the position of an item in a datastructure.
Also incrementing the end iterator does not result in a null iterator. It is undefined behavior. Look at Can an STL map iterator go out of bounds through incrementing?
The iterator is not null when at the end of the list, instead it is equal to the list's end iterator fl.end(). So both iterators need to be passed to the function.
The internal implementation of the iterator depends on the STL library used, for std::forward_list its interface is such that it fulfills the ForwardIterator concept: http://en.cppreference.com/w/cpp/concept/ForwardIterator .

std::vector<std::string> insert empty string instead

In visual studio 2013, I created a std::vector and has store some strings in it. Then I want to make a copy of some string in the vector and append them to the end (suppose to move them to the end, after insert will do erase), but using insert method, I saw only empty strings at the end, very strange. I reproduced it with some simple test code,
std::vector<std::string> v;
std::string s = "0";
for (int i = 0; i < 7; ++i)
{
s[0] = '0' + i;
v.push_back(s);
}
v.insert(v.end(), v.begin(), v.begin() + 3);
for (std::string& s : v)
std::cout << "\"" << s.c_str() << "\" ";
What I get there is
"0" "1" "2" "3" "4" "5" "6" "" "" ""
I debugged into insert method, inside _Insert(..) method of vector class, it did some reallocating of memory, memory move/move and so on.
The first _Umove call move all 7 strings to new allocated memory, I think the std::move is invoked, the old memory has some empty string left.
Then the _Ucopy method try copy 3 items, but from old memory, as a result 3 empty string is attached.
There is another _Umove call, I am not sure what's that for. After all thes, the old memory is freed and new memory attached to the vector.
Using a scalar type like int does not make wrong output, because the memory is copied, no std::move is invoked.
Am I doing something wrong here, or is it a MS Visual Studio's STL bug?
From this std::vector::insert reference:
Causes reallocation if the new size() is greater than the old capacity(). If the new size() is greater than capacity(), all iterators and references are invalidated
[Emphasis mine]
You are adding elements to the vector while iterating the vector using iterators. Since this can cause the vector to be reallocated your iterators will be invalidated. That will lead to undefined behavior.

How to create a string on the heap in D?

I'm writing a trie in D and I want each trie object have a pointer to some data, which has a non-NULL value if the node is a terminal node in the trie, and NULL otherwise. The type of the data is undetermined until the trie is created (in C this would be done with a void *, but I plan to do it with a template), which is one of the reasons why pointers to heap objects are desirable.
This requires me to eventually create my data on the heap, at which point it can be pointed to by the trie node. Experimenting, it seems like new performs this task, much as it does in C++. However for some reason, this fails with strings. The following code works:
import std.stdio;
void main() {
string *a;
string b = "hello";
a = &b;
writefln("b = %s, a = %s, *a = %s", b, a, *a);
}
/* OUTPUT:
b = hello, a = 7FFF5C60D8B0, *a = hello
*/
However, this fails:
import std.stdio;
void main() {
string *a;
a = new string();
writefln("a = %s, *a = %s", a, *a);
}
/* COMPILER FAILS WITH:
test.d(5): Error: new can only create structs, dynamic arrays or class objects, not string's
*/
What gives? How can I create strings on the heap?
P.S. If anyone writing the D compiler is reading this, the apostrophe in "string's" is a grammatical error.
Strings are always allocated on the heap. This is the same for any other dynamic array (T[], string is only an alias to type immutable(char)[]).
If you need only one pointer there are two ways to do it:
auto str = "some immutable(char) array";
auto ptr1 = &str; // return pointer to reference to string (immutable(char)[]*)
auto ptr2 = str.ptr; // return pointer to first element in string (char*)
If you need pointer to empty string, use this:
auto ptr = &"";
Remember that you can't change value of any single character in string (because they are immutable). If you want to operate on characters in string use this:
auto mutableString1 = cast(char[])"Convert to mutable."; // shouldn't be used
// or
auto mutableString2 = "Convert to mutable.".dup; // T[].dup returns mutable duplicate of array
Generally you should avoid pointers unless you absolutely know what are you doing.
From memory point of view any pointer take 4B (8B for x64 machines) of memory, but if you are using pointers to arrays then, if pointer is not null, there are 12B (+ data in array) of memory in use. 4B if from pointer and 8B are from reference to array, because array references are set of two pointers. One to first and one to last element in array.
Remember that string is just immutable(char)[]. So you don't need pointers since string is already a dynamic array.
As for creating them, you just do new char[X], not new string.
The string contents are on the heap already because strings are dynamic arrays. However, in your case, it is better to use a char dynamic array instead as you require mutability.
import std.stdio;
void main() {
char[] a = null; // redundant as dynamic arrays are initialized to null
writefln("a = \"%s\", a.ptr = %s", a, a.ptr); // prints: a = "", a.ptr = null
a = "hello".dup; // dup is required because a is mutable
writefln("a = \"%s\", a.ptr = %s", a, a.ptr); // prints: a = "hello", a.ptr = 7F3146469FF0
}
Note that you don't actually hold the array's contents, but a slice of it. The array is handled by the runtime and it is allocated on the heap.
A good reading on the subject is this article http://dlang.org/d-array-article.html
If you can only use exactly one pointer and you don't want to use the suggestions in Marmyst's answer (&str in his example creates a reference to the stack which you might not want, str.ptr loses information about the strings length as D strings are not always zero terminated) you can do this:
Remeber that you can think of D arrays (and therefore strings) as a struct with a data pointer and length member:
struct ArraySlice(T)
{
T* ptr;
size_t length;
}
So when dealing with an array the array's content is always on the heap, but the ptr/length combined type is a value type and therefore usually kept on the stack. I don't know why the compiler doesn't allow you to create that value type on the heap using new, but you can always do it manually:
import core.memory;
import std.stdio;
string* ptr;
void alloc()
{
ptr = cast(string*)GC.malloc(string.sizeof);
*ptr = "Hello World!";
}
void main()
{
alloc();
writefln("ptr=%s, ptr.ptr=%s, ptr.length=%s, *ptr=%s", ptr, ptr.ptr, ptr.length, *ptr);
}

How understand data() method of boost::array, and return add length?

boost::array<char,7> buf = {'a','b','c','d','e','f','g'};
...
...
std::cout << buf.data() + 5;
It's display: fg
How to understand it?
buf.data() + 5
Thanks
buf.data() seems to return a pointer to the internal array buffer in question.
From there, standard pointer arithmetic applies, and you see the 6th character onwards in the std::cout.operator<< call.
buf.data() is defined to return a pointer to the first element of the array, and the elements in a Boost.Array are defined to be contiguous.
So buf.data() + 5 will be a pointer to the element (in this case, character) of the array.
You could also write &buf[5] and get the same pointer.
Note that in the code above:
std::cout << buf.data() + 5;
you are attempting to print the value of the pointer, not the character it points to.

Resources