I am trying to compare two int arrays, element by element, to check for equality. I can't seem to get this to work. Basic pointer resources also welcome. Thank you!
int *ints;
ints = new int[10];
bool arrayEqual(const Object& obj)
{
bool eql = true;
for(int i=0; i<10; ++i)
{
if(*ints[i] != obj.ints[i])
eql = false;
}
return eql;
}
how about the following?
#inlcude <algorithm>
bool arrayEqual(const Object& obj)
{
return std::equal(ints,ints + 10, obj.ints);
}
Note: the equal function requires both arrays to be of equal size.
When you do if(*ints[i] != obj.ints[i]), what you are comparing is the address pointed by ints[i] with the content of obj.ints[i], instead of the content of ints[i] itself. That is because the name of an array is already a pointer to the first element of an array, and when you add the subscript, you will look for the ith position after the first in that array. That's why you don't need the *.
The correct is:
int *ints;
ints = new int[10];
bool arrayEqual(const Object& obj)
{
bool eql = true;
for(int i=0; i<10; ++i)
{
if(ints[i] != obj.ints[i])
eql = false;
}
return eql;
}
Hope I helped!
I'm surprised nobody's asked why you're using arrays in the first place. While there are places that arrays can be hard to avoid, they're few and far between. Most of your code will normally be simpler using std::vector instead. Since std::vector overloads operator==, all you have to do in this case is something like if (a==b) ... Even in the few places that vector isn't suitable, TR1::array will often do the job (and IIRC, it provides an overload of operator== as well).
I assume this is all wrapped by "class Object {" and "}"?
Just remove the "*" and it should work.
Related
I am trying to create a sorting function with the parameters being a pointer of a list and I am trying to access an element of the given list. Hopefully this code speaks for the problem better than I can:
void bubbleSort(std::vector<int> *L) {
unsigned int i = 0; int temp;
while(isSorted(*L)) {
if(i==L->size()-1) {
i = 0;
}
if(i<L[i]/*<-ERROR here.*/) {
temp = L[i+1]; // ERROR HERE
L[i+1] = L[i]; // ERROR HERE
L[i] = temp; // ERROR HERE
}
}
}
You don't need to painfully dereference every individual use of L (and indeed doing so is error-prone, as you've demonstrated by missing one in your answer).
Instead, just write:
void bubbleSort(std::vector<int> *Lptr) {
auto &L = *Lptr;
and keep the rest of the code the same.
NB. It would be even better to change the function itself, to
void bubbleSort(std::vector<int> &L) {
as it should have been written in the first place, but I'm assuming there's some artificial reason you can't do that.
The function accepts a pointer to an object of type std::vector<int>.
void bubbleSort(std::vector<int> *L) {
To access the original vector using the pointer, you can write either *L or L[0]. That is, both expressions yield an lvalue reference of type std::vector<int> & to the vector.
To get the i-th element of the vector using the subscript operator through the pointer, you can write either (*L)[i] or L[0][i],
However, in this if statement:
if(i<L[i]/*<-ERROR here.*/) {
You are trying to compare the variable i of type unsigned int to the object L[i] of type std::vector<int>. When i is not equal to 0, this yields a non-existent object of the vector type.
It seems you mean something like the following instead:
if ( (*L)[i] < (*L)[i+1] ) {
or:
if ( L[0][i] < L[0][i+1] ) {
or, vice versa:
if ( L[0][i+1] < L[0][i] ) {
Depending on whether the vector is sorted in ascending or descending order.
Pay attention to the fact that there is no sense in declaring the parameter as a pointer to a std::vector<int>. The function would be much clearer and readable if it accepted the vector by reference instead:
void bubbleSort(std::vector<int> &L) {
In this case, the if statement would look like this:
if ( L[i] < L[i+1] ) {
Although I prefer to change the source code as other answer. But, for this question, you can use ->at() function to access the element in a vector pointer.
if(i<L->at(i)) {
temp = L->at(i+1);
L->at(i+1) = L->at(i);
L->at(i) = temp;
}
I was wondering.. Whenever I deal with arrays, when I have to cut it, or sort it, or anything, and then return it, I pass it to the void function like f(array, length, newarray) and in the function declaration I have void f(T *array, int length, T *&new array).
Is there a better way to do this?
Here's some code, I want to remove repeats from an array:
template<class T>
void eliminate(T *niz, int duzina, T *&podniz)
{
int ind;
podniz = new T[duzina];
for (int i = 0; i<duzina; i++)
{
ind = 0;
for (int j = i; j<duzina; j++)
{
if (niz[i] == niz[j])ind++;
}
if (ind == 1)podniz[nova++] = niz[i];
}
}
As already noted in the comments, you really want std::vector.
The main problem with your code is that there is no way to tell how many of the output elements are actually initialized. And accessing uninitialized elements is Undefined Behavior, so you are returning a time bomb to the caller.
With std::vector<T> eliminate(std::vector const&), there's no such doubt. The returned vector has exactly .size() elements.
Vector is also exception-safe. Your code will leak memory if the copy constructor of T throws, e.g. on a std::bad_alloc.
Sure. You can use pointers and pass the array by reference to the function.
Then manipulate the array and return from the function with void type i.e no need of returning the array as it is passed by reference.
so i'm running my head against a wall at the Moment. I want to create a dynamic array, which can contain numbers or text - but most likely numbers.
At the Moment i'm using:
string test[];
for that purpose.
Okay, now the thing is. I want to dynamically fill the array, if the Element is not already in the array. I've tryed googling solution, but most of them came up with vector, which wouldn't work in this case, because the array can be any size.
Again:
Check if the Element is in the Array, that can be empty or not
If Element is not in the Array, put it in.
Anybody got a Solution for this, please? Would be very thankfully!
Thank you very much for all those comments and answers. I just noticed one major difference from between what i found in the net and what you guys posted. if i use test[] it won't work, but if i use test{} everything is fine. Can somebody maybe explain me why is that?
So if I understood correctly you're trying to get an dynamic array which changes its size depending on how much elements are in there? Well then use vector. It does excatly this! And its pretty fast and the C++ standard for tasks like that.
Using a vectoralso allows you to use std::find. So to fullfill your task do something like that:
std::vector<std::string> test{"Hello"};
if (std::find(test.begin(), test.end(), "World!") == test.end())
test.push_back("World!");
Or even better, use std::set wich only allows unique elements:
std::set<std::string> test{"Hello"};
test.insert("World"); // works
test.insert("Hello"); // won't work
If you realy want to use an array then I would recommend you to write a template class to manage the array and then allocate the array on the heap.
template<typename T>
class Array
{
private:
T *data;
unsigned int size;
unsigned int index;
public:
Array()
{
size = 100;
index = 0;
data = new T[size];
}
~Array()
{
delete[] data;
}
void push_back(const T& val)
{
if (index == size)
{ // reallocate data if there is no memory left to store val
std::vector<T> tmp(data, data + size);
delete[] data;
size += 100;
data = new T[size];
for (size_t i = 0; i < tmp.size(); i++)
data[i] = tmp[i];
data[index++] = val;
}
else
{
data[index++] = val;
}
}
T& operator[](const unsigned int& i)
{
if (i >= size)
throw std::runtime_error("i out of bounds");
return data[i];
}
};
You then need to search in the array for an existing value, and if you couldn't find it use push_back to push the value into the array. Or use the subscript operator [] like you're used to.
I want to add two arrays by simply writing:
int a[4] = {1,2,3,4};
int b[4] = {2,1,3,1};
int sum[4] = a + b;
I wrote this function but I got an error
int* operator+(const uint32& other) const{
uint32 sum[n];
for(int i=0; i<n; i++){
sum[i] = (*this[i]) + other[i];
}
return sum;
}
Could you help me on this? Thanks in advance.
Let's go through your code, piece by piece, and look at the problems:
int* operator+(const uint32& other) const{
You can't overload operators for built-in types, so this is doomed from the beginning
Even if you could do this (which you can't), it needs to take two parameters since it's non-member binary function.
uint32 sum[n];
You can't make variable-length arrays in C++ (assuming n isn't a compile-time constant) (note: G++ has some extensions that allow this, but it's non-standard C++)
for(int i=0; i<n; i++){
sum[i] = (*this[i]) + other[i];
There's no this pointer to begin with in this code (it's not a member function)...
const uint32& other is not an array/pointer to an array. It's a single reference to a single uint32. That means that other in this code is not an array/pointer to an array, and so you cannot do other[i] (it's like trying to do int x = 3; x[4] = 13;, which makes no sense).
}
return sum;
You're returning a pointer to a locally allocated array, which means this will result in undefined behavior, as the memory associated with sum is going to get annihilated when this function returns.
}
This is probably wrong, but it appears to work (C++11):
#include <iostream>
#include <array>
using namespace std;
template <class T>
T operator+(const T& a1, const T& a2)
{
T a;
for (typename T::size_type i = 0; i < a1.size(); i++)
a[i] = a1[i] + a2[i];
return a;
}
int main()
{
array<int,5> a1 = { 1, 2, 3, 4, 5 };
array<int,5> a2 = { 2, 3, 4, 5, 6 };
array<int,5> a3 = a1 + a2;
for (int i = 0; i < 5; i++)
cout << a1[i] << '+' << a2[i] << '=' << a3[i] << ' ';
cout << endl;
return 0;
}
Output (ideone):
1+2=3 2+3=5 3+4=7 4+5=9 5+6=11
I think the issue is that you're missing a way to pass in the length of the array. You might need to do something a bit more sophisticated. Something like:
class AddingVector : public std::vector<int>
{
public:
typedef AddingVector type;
type operator+(const AddingVector& rhs, const AddingVector& lhs)
{
/* validate that they're the same size, decide how you want to handle that*/
AddingVector retVal;
AddingVector::const_iterator rIter = rhs.begin();
AddingVector::const_iterator lIter = lhs.begin();
while (rIter != rhs.end() && lIter != lhs.end()) {
retVal.push_back(*rIter + *lIter);
++rIter;
++lIter;
}
return retVal;
}
}
You cannot do that. Non-member binary operators must take two arguments (you only provided one), so you could try this:
int* operator+(const uint32& a, const uint32& b)
But that can't possibly work either, since you want to add arrays, not single uint32 variables. So you would think that this would do it:
int* operator+(const uint32[] a, const uint32[] b)
or:
int* operator+(const uint32[4] a, const uint32[4] b)
But no go. It's illegal because you cannot have pointer types as both arguments in an operator overload. Additionally, at least one of the arguments must be a class type or an enum. So what you're trying to do is already impossible on at least two different levels.
It's impossible to do what you want. One correct way to go about it is to write your own class for an array that can be added to another one.
You cannot overload operators for types other than your own defined types. That is, if you create a class X, you can overload operators for X, but you cannot overload operators for arrays or pointers to fundamental types.
first is your code getting compiled properly, you have used 'n' directly in declaring array, is 'n' declared as constant..
And moreover you have taken a local variable in the function and returning it, well, this return a garbage form the stack, wat i can suggest is you malloc some memory and use it,, but again freeing it would be needed...
Hey, what you could do is,
Take a wrapper class "array"
class array
{
int *ipArr;
DWORD size;
};
then in constructor you can pass the size you want to have an array of
array(DWORD dwSize);
{
// then malloc memory of size dwSize;
}
Have an overloaded operator'+' for this class, that will have the above implementation of adding two int arrays,
Note here you will also need to overlaod the '=' assignment operator, so that our array class can you is directly..
now you can free the associated memory in the destructor
You have a few problems. The first is that you aren't passing in both arrays, and then you don't specify what n is, and the last is that you are trying to pass out a pointer to a local variable. It looks like you are trying to make a member operator of a class.
So basically you are trying to add the contents of an unspecified length array to an uninitialised array of the same length and return the stack memory.
So if you pass in pointers to the arrays and the length of the array and an output array then it would work, but you wouldn't have the syntax
sum = a + b;
it would be something like
addArray(&a, &b, &sum, 4);
To get the syntax you want you could make a class that wraps an array. But that is a much more complicated task.
// All right? This is really good working code?
//Need init array with value "false"
bool **Madj;
int NodeCount=4;
bool **Madj = new bool*[NodeCount];
for (int i=0; i<NodeCount; i++){
Madj[i] = new bool [NodeCount];
for (int j=0; j<NodeCount; j++){
Madj[i][j] = false;
}
}
You could consider using Boost's builtin multi-dimensional array as a less brittle alternative. As noted the code you supplied will work, but has issues.
What about:
std::vector<std::vector<bool> > Madj(4,std:vector<bool>(4, false));
Unfortunately std::vector<bool> is specialized to optimize for size (not speed).
So it can be inefficient (especially if used a lot). So you could use an int array (if you find the bool version is slowing you down).
std::vector<std::vector<int> > Madj(4,std:vector<int>(4, 0));
Note: int can be used in a boolean context and auto converted (0 => false, any other number is true (though best to use 1).
At least IMO, if you insist on doing this at all, you should normally do it rather differently, something like:
class bool_array {
bool *data_;
size_t width_;
// no assignment or copying
bool_array &operator=();
bool_array(bool_array const &);
public:
bool_array(size_t x, size_t y) width_(x) {
data_ = new bool[x*y];
std::fill_n(data_, x*y, false);
}
bool &operator()(size_t x, size_t y) {
return data_[y+width_+x];
}
~bool_array() { delete [] data_; }
};
This can be embellished (e.g., using a proxy to enforce constness), but the general idea remains: 1) allocate your bools in a single block, and 2) put them into a class, and 3) overload an operator to support reasonably clean indexing into the data.
You should also consider using std::vector<bool>. Unlike other instantiations of std::vector, it's not a container (as the standard defines that term), which can be confusing -- but what you're creating isn't a container either, so that apparently doesn't matter to you.
bool **Madj = new bool*[NodeCount];
for (int i=0; i<NodeCount; i++){
Madj[i] = new bool [NodeCount];
for (int j=0; j<NodeCount; j++){
Madj[i][j] = false;
}
}
If the first call to new succeeds but any of the ones in the loop fails, you have a memory leak since Madj and the subarrays up to the current i are not deleted. Use a vector<vector<bool> >, or a vector<bool> of size NodeCount * NodeCount. With the latter option, you can get to element (i,j) with [i*NodeCount+j].
I think this looks fine!
Depending on the use, you could use std::vector instead of a raw array.
But its true that the first Madj declaration should be "extern" to avoid linking or shadowing errors.
If you have only bools, consider using bitsets. You can combine that with other containers for multidimensional arrays, e.g vector<bitset>.