Char array copy fails - c++

I'm copying an array, and for some reason the values aren't the same after the copy. The code is below. In both cases, the _data variable is a char[4]. After the copy, the assert fires. If I examine the two values in the debugger, they show as: 0x00000000015700a8 and 0x00000000015700b0.
_data[0] = rhsG->_data[0];
_data[1] = rhsG->_data[1];
_data[2] = rhsG->_data[2];
_data[3] = rhsG->_data[3];
assert(_data == rhsG->_data);

You've made the mistake of thinking C++ is an easy-to-use high-level language (joke). operator == on C-style arrays compares their address, which of course is different here. You can use std::equal to compare the two arrays, or use a different data structure which supports a more intuitive opeartor ==, such as std::array or std::vector.
You could then also use their operator = to copy them, instead of each element one at a time, assuming the source and destination are the same size. There is std::copy if they are not, or they must be C-style arrays.

If comparing with == you are just comparing two pointers, which value are different. If you want to compare for equality two arrays, you can use memcmp()
assert( ! memcmp(_data, rhsG->_data, 4) );

When you use operator == in assert "_data == rhsG->_data", _data and rhsG->_data are both represented address of the array. So, in your debugger, 0x00000000015700a8 is array address of _data and 0x00000000015700b0 is array address of rhsG->_data. Obviously, they are different, then the assert fires.
After all, array name is always a pointer that point to the first array address in memory.

"_data == rhsG->_data" does not compare the individual elements of two arrays.
The "==" operator is not defined for arrays, so the two parameters are decayed to pointers, which == can work on.

Your assert is comparing the addresses of the two arrays which are different because they are in different memory locations.
If you really want to compare the values, then either loop over them or use memmp.
assert(memcmp(_data, rhsG->_data, 4) == 0);

Related

What exactly do the "==" and "is" operators compare in D?

From "Programming in D" book I learnt that == operator needs to access the objects in order to evaluate the expression on the left and on the right before returning the boolean value. Thus it is not suitable for comparing whether the object is null.
... the == operator may need to consult the values of the members of the objects and that attempting to access the members through a potentially null variable would cause a memory access error.
also
Value equality: The == operator that appears in many examples throughout
the book compares variables by their values. When two variables are said to
be equal in that sense, their values are equal.
So, let's try the following:
import std.experimental.all;
int[] arr = [1, 1, 2, 2, 3];
arr == arr.reverse.array; // --> true
Well, this is unexpected. In Scala for instance the same expression returns False.
It becomes more clear after you check the memory address of both arr and arr.reverse.array -- it does not change. So, now the result of == makes kind of sense although one would expect it to compare values of the arrays not their addresses, right?
Now, let's try is operator which is used to compare object references and should be used to check if the object is null. It is also used to compare class variables.
arr is arr.reverse.array; // --> false
I would expect it to return true as well since it compares references. What is actually going on here? Why does is returns false instead and == returns true?
== DOES compare values. is DOES compare references. Your big mistake is using the function reverse.
http://dpldocs.info/experimental-docs/std.algorithm.mutation.reverse.html
Reverses r in-place.
emphasis mine. That means it modifies the contents of the original.
I suspect you are also checking the memory address wrong. If you are using &arr, you are comparing the address of the local variables, not the array contents. That doesn't change because it is the same local variable, you are just binding to a different array. Check .ptr instead of & and you will see it changes - the .array function always allocates a new array for it.
So == passed because the reverse changed the left hand side at the same time! It wasn't because [1,2,3] == [3,2,1], but rather because after calling reverse, the [1,2,3] was itself modified to [3,2,1] which is == [3,2,1]!.
Now, as to what these operators actually do: == checks for some abstract quality of equality. This varies by type: it can be overridden by member functions (which is why calling it on null classes is problematic) and frequently does a member-by-member comparison (e.g. array elements or struct pieces).
is, on the other hand, does something far simpler: it is a bit comparison of the variable directly, which is closer to an abstract idea of identity, but not quite (like int a = 3; int b = 3; assert(a is b); passes because both are 3 but is it the same identity? fuzzy cuz of value type.)
is will never call a user-defined function, and will never descend into member references, it just compares the bit values.
(interestingly, float.nan is float.nan also returns true, whereas == would not, again just because it compares bit values. But not all nans have the same bit value, so it is not a substitute for isNaN in the math module!)

Is the vector reserved space always linerar? [duplicate]

My question is simple: are std::vector elements guaranteed to be contiguous? In other words, can I use the pointer to the first element of a std::vector as a C-array?
If my memory serves me well, the C++ standard did not make such guarantee. However, the std::vector requirements were such that it was virtually impossible to meet them if the elements were not contiguous.
Can somebody clarify this?
Example:
std::vector<int> values;
// ... fill up values
if( !values.empty() )
{
int *array = &values[0];
for( int i = 0; i < values.size(); ++i )
{
int v = array[i];
// do something with 'v'
}
}
This was missed from C++98 standard proper but later added as part of a TR. The forthcoming C++0x standard will of course contain this as a requirement.
From n2798 (draft of C++0x):
23.2.6 Class template vector [vector]
1 A vector is a sequence container that supports random access iterators. In addition, it supports (amortized)
constant time insert and erase operations at the end; insert and erase in the middle take linear time. Storage
management is handled automatically, though hints can be given to improve efficiency. The elements of a
vector are stored contiguously, meaning that if v is a vector where T is some type other
than bool, then it obeys the identity &v[n] == &v[0] + n for all 0 <= n < v.size().
As other answers have pointed out, the contents of a vector is guaranteed to be continuous (excepting bool's weirdness).
The comment that I wanted to add, is that if you do an insertion or a deletion on the vector, which could cause the vector to reallocate it's memory, then you will cause all of your saved pointers and iterators to be invalidated.
The standard does in fact guarantee that a vector is continuous in memory and that &a[0] can be passed to a C function that expects an array.
The exception to this rule is vector<bool> which only uses one bit per bool thus although it does have continuous memory it can't be used as a bool* (this is widely considered to be a false optimization and a mistake).
BTW, why don't you use iterators? That's what they're for.
As other's have already said, vector internally uses a contiguous array of objects. Pointers into that array should be treated as invalid whenever any non-const member function is called IIRC.
However, there is an exception!!
vector<bool> has a specialised implementation designed to save space, so that each bool only uses one bit. The underlying array is not a contiguous array of bool and array arithmetic on vector<bool> doesn't work like vector<T> would.
(I suppose it's also possible that this may be true of any specialisation of vector, since we can always implement a new one. However, std::vector<bool> is the only, err, standard specialisation upon which simple pointer arithmetic won't work.)
I found this thread because I have a use case where vectors using contiguous memory is an advantage.
I am learning how to use vertex buffer objects in OpenGL. I created a wrapper class to contain the buffer logic, so all I need to do is pass an array of floats and a few config values to create the buffer.
I want to be able to generate a buffer from a function based on user input, so the length is not known at compile time. Doing something like this would be the easiest solution:
void generate(std::vector<float> v)
{
float f = generate_next_float();
v.push_back(f);
}
Now I can pass the vector's floats as an array to OpenGL's buffer-related functions. This also removes the need for sizeof to determine the length of the array.
This is far better than allocating a huge array to store the floats and hoping I made it big enough, or making my own dynamic array with contiguous storage.
cplusplus.com:
Vector containers are implemented as dynamic arrays; Just as regular arrays, vector containers have their elements stored in contiguous storage locations, which means that their elements can be accessed not only using iterators but also using offsets on regular pointers to elements.
Yes, the elements of a std::vector are guaranteed to be contiguous.

How can I sort an array passed as a parameter?

I have to write a method within already-written code that passes me an array directly. However once inside my method that array has become a pointer to the first object in the array. So now I have done some calculations and want to sort the array. But since it's now not considered an array, I can't perform the sort() function.
What's the best way to sort an array when I only have the pointer to work with?
You either need to know the number of elements in the array, passed as a separate parameter or have a pointer to one past the last element.
void my_sort(int* p, unsigned n) {
std::sort(p, p+n);
}
or
void my_sort2(int* p, int* p_end) {
std::sort(p, p_end);
}
and you would call them
int a[] = { 3, 1, 2 };
my_sort(a, sizeof a / sizeof a[0]); // or 3...
my_sort2(a, &a[2] + 1); // one past the last element! i.e. a+3
In c there is essentially no difference between an "array" and a "pointer to the first object in the array". Arrays are referred to using their base pointer, that is, pointer to first object.
Technically precise explanation at Array base pointer and its address are same. Why?
So, just sort the array as you would anywhere else. Got an example sort or sample code in mind or is that sufficient?
Sort it exactly as you would sort it before you passed it in. If your sort() function requires a length, then pass the length as an additional parameter.
The best would be if you could start using std::array from C++11 on:
http://en.cppreference.com/w/cpp/container/array
This way, you would also have the size known and accessible by the corresponding size method. You could also consider other std container types rather than raw array. In general, it is better to avoid raw arrays as much as possible.
Failing that, you would need to know the size of the array either through function parameter, or other means like class member variable if it is happening inside a class, and so on.
Then, you could use different type of sorting algorithms based on your complexity desire; let it be quick sort, bubble sort, heap sort, stable sort, etc... it depends on what kind of data, the array represents, etc.
One sorting algorithm is to use std::sort. Therefore, you would be writing something like this:
std::sort (mystdarray.begin(), mystdarray.end());
or
std::sort (myrawarray, myrawarray+size);

A few C++ vector questions

I'm trying to learn some c++, to start off I created some methods to handle outputing to and reading from a console.
I'm having 2 major problems, marked in the code, manipulating/accessing values within a std::vector of strings passed in by reference.
The method below takes in a question (std string) to ask the user and a vector std strings that contain responses from the user deemed acceptable. I also wanted, in the interest of learning, to access a string within the vector and change its value.
std::string My_Namespace::My_Class::ask(std::string question, std::vector<std::string> *validInputs){
bool val = false;
std::string response;
while(!val){
//Ask and get a response
response = ask(question);
//Iterate through the acceptable responses looking for a match
for(unsigned int i = 0; i < validInputs->size(); i++){
if(response == validInputs->at(i)){
////1) Above condition always returns true/////
val = true;
break;
}
}
}
//////////2) does not print anything//////////
println(validInputs->at(0)); //note the println method is just cout << param << "\n" << std::endl
//Really I want to manipulate its value (not the pointer the actual value)
//So I'd want something analogous to validInputs.set(index, newVal); from java
///////////////////////////////////////////
}
A few additional questions:
3) I'm using .at(index) on the the vector to get the value but I've read that [] should be used instead, however I'm not sure what that should look like (validInputs[i] doesn't compile).
4) I assume that since a deep copy is unnecessary its good practice to pass in a pointer to the vector as above, can someone verify that?
5) I've heard that ++i is better practice than i++ in loops, is that true? why?
3) There should not be a significant difference using at and operator[] in this case. Note that you have a pointer-to-vector, not a vector (nor reference-to-vector) so you will have to use either (*validInputs)[i] or validInputs->operator[](i) to use the operator overload. Using validInputs->at(i) is fine if you don't want to use either of these other approaches. (The at method will throw an exception if the argument is out of the array bounds, while the operator[] method has undefined behavior when the argument is out of the array bounds. Since operator[] skips the bounds check, it is faster if you know for a fact that i is within the vector's bounds. If you are not sure, use at and be prepared to catch an exception.)
4) A pointer is good, but a reference would be better. And if you're not modifying the vector in the method, a reference-to-const-vector would be best (std::vector<std::string> const &). This ensures that you cannot be passed a null pointer (references cannot be null), while also ensuring that you don't accidentally modify the vector.
5) It usually is. i++ is post-increment, which means that the original value must be copied, then i is incremented and the copy of the original value is returned. ++i increments i and then returns i, so it is usually faster, especially when dealing with complex iterators. With an unsigned int the compiler should be smart enough to realize that a pre-increment will be fine, but it's good to get into the practice of using ++i if you don't need the original, unincremented value of i.
I'd use a reference-to-const, and std::find. Note that I also take the string by reference (it gets deep copied otherwise) :
std::string My_Class::
ask (const std::string& question, const std::vector<std::string>& validInputs)
{
for (;;) {
auto response = ask (question);
auto i = std::find (validInputs.begin (), validInputs.end (), response);
if (i != validInputs.end ()) {
std::cout << *i << '\n'; // Prints the value found
return *i;
}
}
}
Read about iterators if you don't understand the code. Of course, feel free to ask other questions if you need.
I'm not going to address points 1 and 2 since we don't know what you are doing and we don't even see the code for ask and println.
I'm using .at(index) on the the vector to get the value but I've read that [] should be used instead, however I'm not sure what that should look like (validInputs[i] doesn't compile).
Subscript access and at member function are different things. They give you the very same thing, a reference to the indexed element, but they behave differently if you pass an out-of bounds index: at will throw an exception while [] will invoke undefined behavior (as builtin arrays do). Using [] on a pointer is somewhat ugly, (*validInputs)[i], but you really should avoid pointers when possible.
I assume that since a deep copy is unnecessary its good practice to pass in a pointer to the vector as above, can someone verify that?
A deep copy is unnecessary, but so is a pointer. You want a reference instead, and a const one since I presume you shouldn't be modifying those:
ask(std::string const& question, std::vector<std::string> const& validInputs)
I've heard that ++i is better practice than i++ in loops, is that true? why?
Its true in the general case. The two operations are different, ++i increments i and returns the new value while i++ increments i but returns the value before the incrementation, which requires a temporary to be hold and returned. For ints this hardly matters, but for potentially fat iterators preincrement is more efficient and a better choice if you don't need or care for its return value.
To answer questions 1 and 2, we'll probably need more information, like: How did you initialize validInputs? What's the source of ask?
3) First dereference the pointer, then index the vector:
(*validInputs)[i]
4) References are considered better style. Especially instead of pointers which never are NULL.
5) For integers, it doesn't matter (unless you evaluate the result of the expression). For other objects, with overloaded ++ operators (iterators, for example) it may be better to use ++i. But in practice, for inline definitions of the ++ operator, it will probably be optimized to the same code.

Equality & assignment operators used on arrays in C++

I was given a homework question that really confuses me. The question is:
In C++ the equality test == may be
applied to arrays, but the assignment
operator = cannot be applied to
arrays. Explain why.
This confuses me, because my understanding is that the == operator would just compare the addresses of the first two elements (which if two arrays were in fact held in separate memory locations, of course would be different). And the = operator, when used like array1 = array2; would just cause array1 to point to the same memory location as array2 does.
What am I missing here? It seems as though either operator can be used, but neither would produce the results typically intended by those operators.
my understanding is that the == operator would just compare the addresses of the first two elements
This is correct: if you compare two arrays using ==, it will compare the addresses of the arrays, so it will only yield true if you compare an array with itself (or with a pointer to an element of the same type). See the description below for why.
the = operator, when used like array1 = array2; would just cause array1 to point to the same memory location as array2 does.
This is not correct because an array is not a pointer. array1 can't point to the same memory location as array2 because array1 isn't a pointer, it's an array of elements.
An array is a sequence of elements. In most contexts, the name of an array is implicitly converted to a pointer to its initial element. This is why you can do things like:
void f(int*);
int data[10];
int* p = data; // this is the same as 'int* p = &data[0];'
f(data); // this is the same as 'f(&data[0]);'
array1 = array2; won't work because arrays are not assignable (mostly for historical reasons; I've never heard a convincing technical reason why it isn't allowed: it was never allowed in C, and C has been around for decades. There's some discussion of this in the comments and answers to Why does C support memberwise assignment of arrays within structs but not generally?).
The following program will not compile:
int main() {
int a[10], b[10];
a = b;
}
For an "assignable" array, you can use the array container-like class found in Boost (boost::array), C++ TR1 (std::tr1::array), or C++0x (std::array). It is actually a class that contains an array; it can be copied and it provides many of the benefits of the Standard Library containers plus the performance characteristics of an array and the ability to use its data as an array when you need to.