Filling array of pointers by function c++ - c++

Hello I have made class gabka and a function f1 to which I would like to pass an array of pointers to fill this array with gabka objects but I get weird error. How to correct it?
error:
cannot convert from gabka to int
the code :
#include <iostream>
using namespace std;
const int n = 4;
class gabka {
public:
float woda;
gabka(){
woda = 0;
}
void f1(gabka t[n]){
for(int i = 0; i < n; i++){
t[i] = new gabka();
}
}
};
int main() {
gabka** t = new gabka*[n];
return 0;
};

Your f1 function takes an array of gabka objects, and you are trying to assign a gabka* to each one of them. You need to decide what you want to pass to f1. For example,
void f1(gabka t[n]){
for(int i = 0; i < n; i++){
t[i] = gabka(); // assign default constructed gabkas
}
}
or
void f1(gabka* t[n]){
for(int i = 0; i < n; i++){
t[i] = new gabka();
}
}
In the latter case, bear in mind you have to call delete on all the elements of t.
It isn't clear what you are intending to do with your code, but, as a general rule, in C++ you should avoid raw pointers and manual dynamic allocation. Prefer standard library containers over dynamically allocates arrays or arrays of dynamically allocated objects.

t[i] = new gabka();
t is an array of gabka, not an array of gabka*.
Either change the declaration of t to be an array of gabka*, or fill it with gabka instances.

Related

Passing and modifying array of vectors through functions in c++

(I'm from C background and new in C++ and its STLs)
I'm writing a C++ array of vectors that will be passed (as a reference of an array of vectors) through a function and will be processed in it.
In this case [in C] I would have passed a pointer to my custom data type (call by value under the hood.)
My code that's giving errors in compile time while trying to do so:
#include <cstdio>
#include <vector>
using namespace std;
/*
the problem is I can't get the syntax. vector<type> &var is
a reference to a single dimension array of vectors.
*/
void pass_arrayOf_vect(vector<int> &array, int lmt);
int main() {
int lmt = 10;
vector<int> lst[lmt];
pass_arrayOf_vect(lst, lmt);
return 0;
}
/*
and the traditional ambiguity of whether using "." or "->" for
accessing or modifying indexes and their members.
*/
void pass_arrayOf_vect(vector<int> &lst, int lmt) {
for (int i = 0; i < lmt; i++) {
lst[i].push_back(i*i);
}
for (int i = 0; i < lmt; i++) {
printf("array[%d]: ", i);
for (int j = 0; j < lst[i].size(); j++) {
printf("%d ",lst[i][j]);
}
printf("\n");
}
printf("\n");
return;
}
In the main function the lst variable is an array of vectors. When you pass this to the pass_arrayOf_vect function you pass a pointer to the first element.
I.e. when you do
pass_arrayOf_vect(lst, lmt);
it's actually the same as doing
pass_arrayOf_vect(&lst[0], lmt);
So the function you call needs to accept a pointer to a vector as its first argument (not a reference):
void pass_arrayOf_vect(vector<int> *array, int lmt);
// ^
// Note use of asterisk instead of ampersand
An even better solution would be to use an std::array of vectors instead. Or if you're on an older compiler without support for std::array, or need the amount to be run-time configurable (in which case you can't use plain C-style arrays anyway), use a vector of vectors.

c++ assign a 2D array to an Object

My code pass the compiler, but I have a question about the concept of the pointer.
main.cpp:
int main(int argc, const char * argv[])
{
int inputPuzzle[3][3];
std::cout << "Set the puzzle: " << "\n";
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
std::cin >> inputPuzzle[i][j];
}
}
puzzle puzzle_1 = *new puzzle(inputPuzzle);
puzzle_1.display();
return 0;
}
puzzle.h:
class puzzle
{
public:
puzzle();
puzzle(int [][maxCol]);
~puzzle();
public:
int puzz [maxRow][maxCol];
};
puzzle.cpp:
puzzle::puzzle(int a[][maxCol])
{
for (int i = 0; i < maxRow; i++) {
for (int j = 0; j < maxCol; j++) {
puzz[i][j] = a[i][j];
}
}
}
My question is about the statement :puzzle puzzle_1 = *new puzzle(inputPuzzle);
Why do I have to add "*" in front of the new object in which I want to assign a 2D array ?
You're programming C++, where new returns a pointer. When you use the asterisk it's the dereference operator, and basically turns a pointer into a non-pointer.
Using the dereference operator like that means that you actually lose the pointer created by new, and you can not free that allocated memory with delete which, of course, leads to a memory-leak.
To avoid losing the pointer, you have to declare the variable as a pointer:
puzzle* puzzle_1 = new puzzle(inputPuzzle);
Then you have to use the pointer member selector operator instead when accessing members:
puzzle_1->display();
And, to avoid leaking memory, when you're done with the pointer you must delete it:
delete puzzle_1;
However, in C++ there is seldom any need to use pointers; instead just declare it as a normal variable:
puzzle puzzle_1(inputPuzzle);
puzzle_1.display();
Unrelated to your question, but if maxRow or maxCol is larger than 3, then you will read from outside the memory for the array inputPuzzle. This will lead to undefined behavior.
The most important part here is the new keyword. It returns a pointer to the newly instantiated object. Check the Dynamic memory allocation for more information and to understand when and how to use pointers, and how the new keyword works.
Now, we know that the new keyword returns a pointer, and you want to obtain an object not a pointer, hence you have to dereference your pointer.
Two correct solutions now:
// without pointers
puzzle puzzle_1(inputPuzzle); // initialize the object without going through a copy
puzzle_1.display();
// with pointers
puzzle *puzzle_1 = new puzzle(inputPuzzle);
puzzle_1->display(); //notice that we used -> here as it's a pointer
// do stuffs here
delete puzzle_1; // free the memory

Accessing an entire row of a multidimensional array in C++

How would one access an entire row of a multidimensional array?
For example:
int logic[4][9] = {
{0,1,8,8,8,8,8,1,1},
{1,0,1,1,8,8,8,1,1},
{8,1,0,1,8,8,8,8,1},
{8,1,1,0,1,1,8,8,1}
};
// I want everything in row 2. So I try...
int temp[9] = logic[2];
My attempt throws the error:
array initialization needs curly braces
I know I can retrieve the row using a FOR loop, however I'm curious if there was a more obvious solution.
That's not how arrays/pointers work in C++.
That array is stored somewhere in memory. In order to reference the same data, you'll want a pointer that points to the the beginning of the array:
int* temp = logic[2];
Or if you need a copy of that array, you'll have to allocate more space.
Statically:
int temp[9];
for (int i = 0; i < 9; i++) {
temp[i] = logic[2][i];
}
Dynamically:
// allocate
int* temp = new int(9);
for (int i = 0; i < 9; i++) {
temp[i] = logic[2][i];
}
// when you're done with it, deallocate
delete [] temp;
Or since you're using C++, if you want to not worry about all this memory stuff and pointers, then you should use std::vector<int> for dynamically sized arrays and std::array<int> for statically sized arrays.
#include <array>
using namespace std;
array<array<int, 9>, 4> logic = {
{0,1,8,8,8,8,8,1,1},
{1,0,1,1,8,8,8,1,1},
{8,1,0,1,8,8,8,8,1},
{8,1,1,0,1,1,8,8,1}
}};
array<int, 9> temp = logic[2];
As well as decaying the array to a pointer, you can also bind it to a reference:
int (&temp)[9] = logic[2];
One advantage of this is it will allow you to use it C++11 range-based for loops:
for (auto t : temp) {
// stuff
}
A direct assignment won't work. C++ does not allow that. At best you'll be able to assign them to point to the same data - int *temp = logic[2]. You'll need a for loop or something like the below.
I believe this would work:
int temp[9];
memcpy(temp, logic[2], sizeof(temp));
But I'd generally suggest using std::vector or std::array instead.

Allocate memory in a function where the data type is determined by a pass-in value

I would like to allocate memory for 3D array inside a function.
void*** myFunc(int myType){
double ***p2DArray;
// Allocate memory
p2DArray = new double**[HEIGHT];
for (int i = 0; i < HEIGHT; ++i) {
p2DArray[i] = new double*[WIDTH];
for (int j = 0; j < WIDTH; ++j) {
p2DArray[i][j] = new double[DEPTH];
for (int k = 0; k < LENGTH; ++k)
p2DArray[i][j][k] = 0;
}
}
return p2DArray;
}
In the code above, double type is created. My question is that how to create different data types according to the myType parameter? I don't want to copy the above code twice by the way.
When you find yourself wanting to pass a type to a function in C++ you need to use templates:
template <typename T>
T*** func() {
T*** array;
array = new T**[HEIGHT];
...
return array
}
You can then call this function like so:
double*** var = func<double>();
When the compiler sees a call to func<double>() it will look up the template for func() and generate a regular (non-template) function that simply replaces all the T's with double.
For this design you should consider using a idiomatic C++ container such as a vector. This provides a number of features that will make your code safer and more readable such as iterators.
One option for vectors is simply to replace your array with vector<vector<vector<T>>>. Another option is to use a single vector<T> with a size of WIDTH * HEIGHT * DEPTH.

Taking integer as parameter and returning an array

I want to create a function that takes an integer as it's parameter and returns an array in C++. This is the pseudo-code I had in mind:
function returnarray(integer i)
{
integer intarr[i];
for (integer j = 0; j < i; j++) { intarr[j] = j; }
return intarr;
}
I tried the common way of declaring returnarray as function* returning a pointer, but then I can't take an integer as my parameter. I also can't assign j to intarr[j]. I'd really like to avoid making a pointer to an int just so I could use the parameter.
Is there any way of doing this and being able to assign j to intarr[j] without making a pointer for it?
EDIT:
forgot to write that I want to avoid vectors. I use them only if I really have to! (my reasons are mine).
Thanks :D
You can't return a stack-allocated array- it's going to go out of scope and the memory deallocated. In addition, C++ does not allow stack-allocated variable-length arrays. You should use a std::vector.
std::vector<int> returnarray(int i) {
std::vector<int> ret(i);
for(int j = 0; j < i; j++) ret[j] = j;
return ret;
}
your code isn't even near valid c++ so i assume you're total beginner
use std::vector
#include <vector>
std::vector<int> yourFunction( int n )
{
std::vector<int> result;
for( int i = 0; i < n; ++i )
{
result.push_back( i );
}
return result;
}
Disclaimer: code untouched by compilers' hands.
Cheers & hth.,
Two remarks, before using the excellent #DeadMG 's solution:
1) You never want to avoid vectors. If v is a vector, and you really want a pointer, you can always have a pointer to the first element by writing &v[0].
2) You can't return an array. You will return a pointer to a fresh memory zone that you'll have to delete once finished with it. Vectors are only arrays with an automatic deletion facility, so you won't leak memory.
You need to use dynamic memory. Something like this
int* returnArray(int size) {
int* array = new int[size];
for(int i = 0; i < size; ++i)
array[i] = i;
return array;
}
Not that I'd particularly recommend this approach in general, but you can use templates to do this without resorting to dynamic memory allocation. Unfortunately you can't return arrays from functions, so you'd need to return a struct with the array inside.
template <int N>
struct int_array_type {
int ints[N];
};
template <int N>
int_array_type<N> returnarray() {
int_array_type<N> a;
for (int i = 0; i < N; ++i)
a.ints[i] = i;
return a;
}
...
int_array_type<10> u = returnarray<10>();
std::copy(u.ints, u.ints+sizeof(u.ints)/sizeof(u.ints[0]),
std::ostream_iterator<int>(std::cout, "\n"));