Returning array - c++

How to return a pointer to array and get values from that?
int * getChange(int first[], int second[], int SIZE) {
int i = 0;
int * change = new int[2];
for (i = 0; i < SIZE; i++) {
if (first[i] != second[i]) {
change[0] = first[i];
change[1] = second[i];
}
break;
}
return change;
}
function main() {
int myNumbers[] = {1, 0, 2, 3};
int possibilities[] = {0, 1, 2, 3};
int * change;
change = getChange(possibilities, myNumbers, 4);
printf("%i / %i\n", (change), (change+1));
}
Unfortunately the function seems to return addresses, not values...

Try to change
printf("%i / %i\n", (change), (change+1));
to
printf("%i / %i\n", *(change), *(change+1));
In the printf function you need to use an int as parameters, not an int*. the change variable is a pointer. You must use *change and, using pointers arithmetics, *(change + 1)
Obviously, don't forget to free the allocated memory.

In C++, you would not be using arrays (int[] or int*), because they are annoying in several ways: you have to pass around the SIZE, they're usually exception-unsafe (you have to catch the exception, delete the array, then re-throw the exception), and they're hard to use as class members properly. Either use a standard library container, or an iterator range.
The idiomatic way to do what you're trying to do would be to use iterators and pairs:
template <typename IT_1, typename IT_2>
std::pair<int,int> getChange(IT1 begin, IT1 end, IT2 begin2)
{
for (; begin != end; ++begin, ++begin2)
{
if (*begin != *begin2) return std::make_pair(*begin,*begin2);
}
return std::make_pair(0,0);
}
void main() {
int myNumbers[] = {1, 0, 2, 3};
int possibilities[] = {0, 1, 2, 3};
std::pair<int,int> change = getChange(possibilities, possibilities + 4,
myNumbers);
printf("%i / %i\n", change.first, change.second);
}
Note that the second sequence (myNumbers) is expected to be as least as long as the first sequence. If you're not comfortable with iterators and function templates yet, you can always use vectors instead:
std::pair<int,int> getChange(std::vector<int> a, std::vector<int> b) {
for (int i = 0; i < a.size() && i < b.size(); ++i)
{
if (a[i] != b[i]) return std::make_pair(a[i],b[i]);
}
return std::make_pair(0,0);
}
void main() {
int _myNumbers[] = {1, 0, 2, 3};
int _possibilities[] = {0, 1, 2, 3};
std::vector<int> myNumbers(_myNumbers,_myNuymbers+4),
possibilities(_possibilities,_possibilities+4);
std::pair<int,int> change = getChange(possibilities, myNumbers);
printf("%i / %i\n", change.first, change.second);
}
While the latter may seem rather more verbose than the array version (after all, it's creating two arrays and then copying their values into the vectors), keep in mind that initializing an array from a constant is a fairly rare occurence: most of the time, arrays (and vectors) are initialized dynamically by a piece of code dedicated to just that. Such code can usually be used for both arrays and vectors with only minimal changes.
And, of course, you can typedef both std::pair<int,int> and std::vector<int> to shorter names if you end up using them a lot.

As it has been said, your code is very wrong in very many levels. I'll try to explain.
First of all, if you want to return the same array, why are you creating a new one? What is it you want to do, exactly?
Second, that new you make is never getting free'd. After main() exits, all the memory of your application is going to be claimed by the OS, but you shouldn't rely on that.
The code that Chowlett wrote is correct (+1 for being nice and pointing out the allocation problem ;), so I'll just go through your code and point out stuff
for(int i = 0 ; i < size i++)
{
if(first[i] != second[i])
{
change[0] = first[i];
change[1] = second[i];
}
break;
}
that doesn't do what you want. It checks if first[0] is different from second[0], then hits the break whether this holds true or not. You want the break inside the if statement block.
then if you want to use an array's content, you have to index it with [], otherwise you refer to the memory address of the array and it's indexes. This means which's been said, that you want to do
printf("%d / %d", changed[0], change[1])
While what's been said above that using C++ vectors is "better" for this case than arrays, I don't think this is the right answer to your question. You seem to be learning how to use arrays, and arrays are a most important part of C and even C++ real life coding. You'll use them a lot, they are WAY faster than vectors, and many many many libraries that you'll deal with are written in plain C, so you'll have to use them.
Learn yourself a little bit of pointer arithmetics, and you'll be fine. Remember to free the memory you allocate, this isn't Java. remember that a in
int a[3];
is more like a
int *a;
than like a
int a;
which explains why you can also do
printf("%d / %d", *changed, *(changed + 1));
Read the kernighan and ritchie.
Happy hacking

I think I'd write it a bit differently (and note that I'm sticking to C-only concepts here - in C++ I would almost certainly do things a bit differently):
void getChange(int *first, int *second, int SIZE, int *change) {
int i = 0;
for (i = 0; i < SIZE; i++) {
if (first[i] != second[i]) {
change[0] = first[i];
change[1] = second[i];
break;
}
}
return;
}
function main() {
int myNumbers[] = {1, 0, 2, 3};
int possibilities[] = {0, 1, 2, 3};
int change[2];
getChange(possibilities, myNumbers, 4, change);
printf("%i / %i\n", change[0], change[1]);
}
If you allocate change outside of getChange you solve potential memory leak problems.

printf("%i / %i\n", (change), (change+1));
This should be:
printf("%d / %d\n", *change, *(change + 1));

int* functionReturningArray( int *inputArray, int size)
{
int*outputArray = new int[20];
return outputArray;
}
But it is much better to use vector in c++ then c style arrays. Because it protect you from a lot of errors and it is faster to write code using vector.
Also such functionReturningArray is not very good because it returns just a pointer t othe first element of array but don't return size. You can return size and a pointer (two arguments) by predefining them and passing pointers to them to your function like this:
void f(int**outputArray, int *size)
{
*outPutArray = new int[20];
*size = 20;
}
And how it looks with a vector:
std::vector<int> func(const std::vector<int> &input)
{
std::vector<int> output;
output.push_back(5);
return output;
}
You can also create the vector on a heap and return a pointer to it.
But avoid using std::vector - use std::string instead

Related

How to remove integers in array less than X in C++?

I found the same question for PHP and I tried to do the same in C++.
I tried following:
// returns new array with numbers lower then "number", len is set to
// new length.
int * filter(int array[], int &len, int number) {
int cnt = 0;
for (int i = 0; i < len; i++) {
if (array[i] < number) {
cnt++;
}
}
int *ret = new int[cnt];
cnt = 0;
for (int i = 0; i < len; i++) {
if (array[i] < number) {
ret[cnt] = array[i];
cnt++;
}
}
len = cnt;
return ret;
}
This function will create a new array with the integers that are lower than the integer number. I tried to bypass the problem that I don't know how long the new array should be.
Is there any better way to solve this problem?
Yes, use std::vector type. It will automatically handles allocations for you each time you push value to it (using push_back method).
Example
#include <iostream>
#include <vector>
int main() {
std::vector<int> a;
a.push_back(1);
a.push_back(2);
for (int value : a) {
std::cout << value << '\n';
}
}
It's also a good idea to avoid new syntax, as it doesn't automatically deallocate, unlike std::vector.
Also, while this is unrelated to question, C++ provides a function that does what you want already called std::copy_if.
std::remove is the algorithm you're looking for.
#include <iterator>
#include <algorithm>
int main()
{
int array[4] = {1, 42, 314, 42};
// If you only know `array` as a pointer, and `len`, then
// `std::begin(array)` becomes `array`, and
// `std::end(array)` becomes `array + len`.
auto end = std::remove(std::begin(array), std::end(array), 42);
// Now `end` points to the "new end" of the array.
// And `std::distance(std::begin(array), end)` is the "new length".
}
It moves all matched elements (42 in the example) to the end of the array. When inspecting array after std::remove runs, you get {1, 314, 42, 42}, and end points past the last nonmatching element (the first 42 in this case).
It's also possible to copy the nonmatching elements to another array using std::remove_copy, or std::copy_if, but in order to do this, you'll have to allocate another array of elements. At this point, you're better off using a dynamic growing array such as std::vector. In that case, use std::vector::erase like here in the answers with std::remove.

Sorting one array based on another in place [duplicate]

This question already has answers here:
Sorting zipped (locked) containers in C++ using boost or the STL
(5 answers)
Closed 7 years ago.
I'm coding in C++ (with c++11 standards) and I have two big arrays of built-in type that I want to sort the second one based on the first.
here is an example:
A = {1, 5, 4, 3, 6, 2};
B = {1, 2, 3, 4, 5, 6};
after sorting:
A = {1, 2, 3, 4, 5, 6};
B = {1, 6, 4, 3, 2, 5};
It's as if each element B[i] is attached to element A[i] and you just sort array A. So elements in B move according the corresponding element in A. I know this questions has been asked over and over, yet the only solution I've come across with is to use pair<type 1, type 2>. But considering the arrays are big, it takes quite a while to allocate the memory for pairs array and copy arrays back and forth.
But I believe the sorting can be done in-place, i.e., using only O(1) memory. In fact if std::sort allowed for costume swap it would have been fine. Because I assume that's the only thing beyond comparator that sorting algorithms use.
A = vector<double>(1e6); // some random numbers
B = vector<double>(1e6); // some random numbers
Comp comp(&A,&B);
Swap swap(&A,&B);
costume_sort(A,B,comp,swap); // some sort function that can take costume swap and compare
class Comp {
vector<double> *A;
vector<double> *B;
Comp(vector<double> *A, vector<double> *B) : A(A),B(B) {};
bool compareTo(size_t i, size_t j) { return A->at(i) < A->at(j); };
};
class Swap {
vector<double> *A;
vector<double> *B;
Swap(vector<double> *A, vector<double> *B) : A(A),B(B) {};
void swapFnc(size_t i, size_t j) { swap(A->at(i), A->at(j));swap(B->at(i), B->at(j)); };
};
Is there any function in STL or other libraries available that can do that? This is a sort of pseudo-code of the idea I'm trying to explain here. Obviously it's not precise but I hope it's clear what I mean.
You can sort based on indices similar to the related post: std::sort and custom swap function.
It is not a custom swap function and allocateds some more memory, but should perform well.
If you are defining the types, then you can overload std::swap to do what you want: How to overload std::swap().
No there is not an std:: function that meets your requirements.
Although it's possible to provide its custom comparison (so Q&A) and swap (so Q&A) functor, those take a (constant) reference to the items to compare or swap, not an index on an hypothetical container. Indeed those functors should have meaning for comparisons and swaps of non-contained objects.
Example of reorder a[] and b[] in place according to a sorted array of pointers to a[]. Since an array of pointers is used, the compare function only needs to know the type of elements being compared. The reorder in place code time complexity is O(n), every store places a value in its sorted location. Note that the array of pointers is restored to it's original state (&a[0] ... &a[n-1]) during the reorder.
bool compare(const int *p0, const int *p1)
{
return *p0 < *p1;
}
int main()
{
int a[8] = {7,5,0,6,4,2,3,1};
char b[8] = {'h','f','a','g','e','c','d','b'};
int *pa[8];
size_t i, j, k;
int ta;
char tb;
// create array of pointers to a[]
for(i = 0; i < sizeof(a)/sizeof(a[0]); i++)
pa[i] = &a[i];
// sort array of pointers to a[]
std::sort(pa, pa+sizeof(a)/sizeof(a[0]), compare);
// reorder a[] and b[] according to the array of pointers to a[]
for(i = 0; i < sizeof(a)/sizeof(a[0]); i++){
if(i != pa[i]-a){
ta = a[i];
tb = b[i];
k = i;
while(i != (j = pa[k]-a)){
a[k] = a[j];
b[k] = b[j];
pa[k] = &a[k];
k = j;
}
a[k] = ta;
b[k] = tb;
pa[k] = &a[k];
}
}
for(i = 0; i < sizeof(a)/sizeof(a[0]); i++)
std::cout << a[i] << ' ';
std::cout << std::endl;
for(i = 0; i < sizeof(b)/sizeof(b[0]); i++)
std::cout << b[i] << ' ';
std::cout << std::endl;
return 0;
}

Returning Array from C++ Function

I'm teaching myself C++ and doing a problem from a textbook. So far I have covered the basics such as data types, declarations, displays, assignment, interactive input, selection (if-else), and repetition (for/while loops...), functions and arrays. I have NOT done anything with pointers, but I know what they are...
I came across this problem:
The answers to a true-false test are as follows: T T F F T. Given a two-dimensional answer array, in which each row corresponds to the answers provided on one test, write a function that accepts the two-dimensional array and number of tests as parameters and returns a one-dimensional array containing the grades for each test. (Each question is worth 5 points so that the maximum possible grade is 25.) Test your function with the following data:
My understanding is that C++ functions cannot return arrays--At least this is what I read on other posts on this forum. Is this correct? If so, how are they expecting you to do this problems because I haven't covered pointers yet. The only other way I thought MIGHT be possible is by passing in the array by reference.... but the question stem only says there are 2 arguments to the function so I thought maybe that method was ruled out. That method would require a third argument which is the array your modifying so its implicitly returned.
I have some code, but its not correct (only my calcgrade function needs work) and I'm not sure how to move forward.Could someone please advise? Thank you!!
#include<iostream>
// Globals
const int NROW = 6, NCOL = 5;
bool answers[NCOL] = {1, 1, 0, 0, 1};
bool tests[][NCOL] = {1, 0, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 0, 0, 1,
0, 1, 0, 0, 0,
0, 0, 0, 0, 0,
1, 1, 0, 1, 0};
int grade[NROW] = {0};
// Function Proto-Types
void display1(bool []);
void display2(bool [][NCOL]);
int calcgrade(bool [][NCOL], int NROW);
int main()
{
calcgrade(tests, NROW);
display2(tests);
return 0;
}
// Prints a 1D array
void display1(bool answers[])
{
// Display array of NCOL
for(int i = 0; i < NCOL; i++)
std::cout << std::boolalpha << answers[i] << std::endl;
return;
}
// Print 2d Array
void display2(bool answers[][NCOL])
{
// Display matrix: 6x5
for(int i = 0; i < NROW; i++)
{
for(int j= 0; j < NCOL; j++)
{
std::cout << std::boolalpha << answers[i][j] << std::endl;
}
std::cout << std::endl;
}
return;
}
int calcgrade(bool tests[][NCOL], int NROW)
{
for(int i = 0; i < NROW; i++)
{
for(int j = 0; j < NROW; j++)
{
if(tests[i][j]==answers[j])
grade[i] += 5;
}
printf("grade[%i] = %i", i, grade[i]);
}
return grade;
}
Try to use std::vector.
Vectors are sequence containers representing arrays that can change in size.
You can do so:
vector<bool> function()
{
vector<bool> vec;
vec.push_back(true);
vec.push_back(false);
vec.push_back(true);
return vec;
}
If you're passing the number of tests as the second parameter, it means you actually know the number of tests, so you don't need to use a vector. You can return an dynamically allocated array (either using new or malloc).
The code would look like this:
int* calcgrade(bool tests[][NCOL], int NROW){
int* array = new int[NROW];
for(int i=0;i<NROW;i++)
array[i] = calculatedGrade;
return array;
}
You can:
as you said, return pointer to dynamically allocated array,
you can make structure type with word struct that includes static array, read more on C++ Reference and return/take as argument structure of your type.
Another way of doing this would be to create the Answer array in your main function, then pass it along with the T/F array to your grading function. Then, your grading function could operate on the Answer array, and wouldn't even need to return anything.
Essentially, when you pass arrays in functions, you're actually passing pointers to the arrays, and thus you can operate on them as if they were passed by reference (which they were).
semi-pseudocode ex:
void getGrades( const int answerVector, int gradeVector ) {
// code that computes grades and stores them in gradeVector
}

Finding the Intersect of 'n' Generic Arrays

EDIT : Added far more detail.
I'm trying to write an algorithm that finds the intersection (points common to all) of n arrays. My program takes these arrays and stores them in a two dimensional array on which the operations take place. For example, here is a sample main method:
int a[] = { 12, 54, 42 };
int b[] = { 54, 3, 42, 7 };
int c[] = { 3, 42, 54, 57, 3 };
IntersectionTableau<int> x(3); // Where 3 is the max number of arrays allowed
// to be stored.
x.addArray(a, 3);
x.addArray(b, 4);
x.addArray(c, 9);
x.run(); // Finds the intersection.
These added arrays will be stored in T** arrays and their sizes in int* sizes. T is a generic type. What is an efficient algorithm that will let me do this on a variable number of arrays of generic types?
Here is what I'm currently attempting to do:
template <class T>
inline
void IntersectionTableau<T>::run() {
T* commonElements = d_arrays[0];
for (int i = 1; i < d_currentNumberOfArrays; ++i) {
commonElements = getIntersection(commonElements, d_arrays[i], d_sizes[i - 1], d_sizes[i]);
}
d_results = commonElements;
}
template <class T>
inline
T* IntersectionTableau<T>::getIntersection(T* first, T* second, int sizeOfFirst, int sizeOfSecond) {
T* commonElements;
if (sizeOfFirst > sizeOfSecond) {
commonElements = new T[sizeOfFirst];
} else {
commonElements = new T[sizeOfSecond];
}
for (int i = 0; i < sizeOfFirst; ++i) {
for (int j = 0; j < sizeOfSecond; ++j) {
if (first[i] == second[i]) {
commonElements[i] = first[i];
}
}
}
return commonElements;
}
The first function takes the first two arrays and sends them to the second function, which returns an array of the intersections between those two arrays. Then, the first function compares the intersection array with the next array in d_arrays and so on. My problem is when I go to print out an element from d_results a garbage value is produced, and I'm unsure why. Could someone tell me what I'm doing wrong, or alternatively, a better way to accomplish this?
There are at least two problems in the code:
if (first[i] == second[i])
This should be if (first[i] == second[j]).
commonElements[i] = first[i];
This is trickier to fix. I think you want to have another variable (neither i nor j); let's call it k:
commonElements[k++] = first[i];
Anyway, since you can use C++, you can use a std::vector instead. It stores its size inside; this will reduce confusion:
template <class T>
std::vector<T> // note: adjusted the return type!
IntersectionTableau<T>::getIntersection(...)
{
std::vector<T> commonElements;
for (int i = 0; i < sizeOfFirst; ++i) {
for (int j = 0; j < sizeOfSecond; ++j) {
if (first[i] == second[j]) {
commonElements.push_back(first[i]);
}
}
}
return commonElements;
}
You can turn first and second into vectors too (though you won't benefit much from it right now).
Here are some points to note:
I changed the return type to vector<T>
The old version, which returns an array, requires additional code to specify the length of its result; this version returns the length inside the vector<T> object
The old version, which returns an array, requires delete[] array somewhere later, to prevent a memory leak
The vector-to-pointer hack &commonElements[0] will not work for an empty vector
If your other code works with an array/pointer, you can use the vector-to-pointer hack &commonElements[0], but outside the function, in order to respect the lifetime rules:
T* commonElements = NULL;
for (int whatever = 0; whatever < 10; ++whatever)
{
std::vector<T> elements = xxx.getIntersection(...); // will work
commonElements = &elements[0]; // can pass this pointer to a function receiving T*
print(commonElements); // will work
}
print(commonElements); // cannot possibly work, will probably segfault
print(elements); // cannot possibly work, and compiler will reject this

C++ Dynamic multidimensional array problem

I'm developing a 2d-platformer. Everything was fine until I've got some hard to solve problem. Level map is stored in dynamic multidemension array(char **map). It works fine, until I want to redefine it
Here's the part of code:
Map& Map::operator=(const Map& rhs)
{
if(width!=0||height!=0)
{
for(int i=0;i<width;i++)
delete[] map[i];
delete[] map;
} //deleting previously created array
height=rhs.height;
width=rhs.width; //receiving other map's size
map=new char* [width];
walkmap=new unsigned char* [width];
objmap=new char* [width];
for(int i=0;i<width;i++)
{
*(map+i)=new char[height];
} //creating new array
for(int h=0;h<height;h++)
for(int w=0;w<width;w++)
{
map[w][h]=rhs.map[w][h];
} //receiving new values
//...
}
Everything works fine for the first time, but when I need to redefine array for the second time my program crashes at the part, when array is receiving new values from another one. May be I miss something, but I can't find it! I was searching for this problem, but didn't find what I am doing wrong. Help me, please.
As always, Boost has an elegant and memory efficient multi-dimensional array class:
http://www.boost.org/doc/libs/1_39_0/libs/multi_array/doc/user.html
For example, to setup a 10 x 20 array of bool values:
boost::multi_array mtaFlagMatrix(boost::extents[10][20]);
Then to access its elements:
mtaFlagMatrix[2][6] = false; // indexes are zero-based - just like normal C arrays
...
if ( mtaFlagMatrix[2][6] )
{
...
}
Then, you can resize the array this way (existing values are preserved):
typedef boost::multi_array array_type;
array_type::extent_gen extents;
array_type A(extents[3][3][3]);
A[0][0][0] = 4;
A[2][2][2] = 5;
A.resize(extents[2][3][4]);
assert(A[0][0][0] == 4);
// A[2][2][2] is no longer valid.
This saved me a lot of time testing for extreme cases.
Your 2d array is not freeed properly. I advise you to use the Iliffe way of allocating 2d arrays which is faster and safer to use:
char** alloc_array( int h, int w )
{
typedef char* cptr;
int i;
char** m = new cptr[h];
m[0] = new char[h*w];
for(i=1;i<h;i++) m[i] = m[i-1]+w;
return m;
}
void release_array(char** m)
{
delete[] m[0];
delete[] m;
}
int main()
{
int r,c;
char** tab;
int width = 5;
int height = 3;
tab = alloc_array(height, width); /* column first */
for(r = 0;r<height;++r)
for(c = 0;c<width;++c)
tab[r][c] = (1+r+c);
for(r = 0;r<height;++r)
{
for(c = 0;c<width;++c)
{
printf("%d\t",tab[r][c]);
}
puts("");
}
release_array(tab);
}
This can be easily encapsulated in a neat 2d-array class or made to use std::vector instead of raw allocation. Prefer this way of doing 2d array as it is cache friendly , style provide the [][] access and is no slower and soemtimes faster than the polynomial 1d access.