Returning array from function - c++

Been trying to get this to work for hours with many different methods but still can't get it to work...
Main class:
WinHandle wh;
int* myarr;
myarr = wh.getpos;
cout << "left: " << *(myarr) << endl;
WinHandle.cpp class:
int* WinHandle::getpos(){
int pos[4];
//code
pos[0] = 2;
//code
return pos;
}
WinHandle.h file:
int* getpos();
That's just my last method, tried various others to no avail. Any help?
Keep getting
non-standard syntax; use '&' to create a pointer to member
and
cannot convert from 'int *(__thiscall WinHandle::* )(void)' to 'int *'

A plain array cannot be returned directly from a function.
Use std::array, instead.

Your immediate source of compilation error is wrong syntax. When you are calling the function, you need to call it with parenthesis: wh.getpos(). However, this is a lesser of a problem. A much bigger problem is that you are returning an array which is local to your function. This won't do, this array will be destroyed once you exit the function, and you will end up with a pointer to deleted object. Say 'Hi' to undefined behavior.
To fix the problem, you need to return either std::vector or std::array.

The best solution is to use std::array (or std::vector) because it's the most flexible. Otherwise, you could create the array outside the method, then use a reference parameter to operate on it inside wh.getpos().

Related

How to save more pointers in one array

I want to make a pointer to an instance of a class. Many instances - that is why I made an array which saves all of those.
But how can I set the value of a pointer in a class to 0?
That is the code... Maybe you know what I'm talking about
public:
CCharacter *pTeamMember[15];
And in another file:
pTeams[team]->pTeamMember = 0;
It causes following error.
error C2440: '=' can't convert 'int' into 'CCharacter *[15]
What I don't understand is, that this don't causes any errors:
public:
Team *pTeams[31];
And in another file:
pTeams[i] = 0;
Does anyone have ideas?
pTeamMember isn't a pointer. It's an array of pointers-to-CCharacter.
In your second example, you're assigning to one of the pointers in the array. You could do the same with pTeamMember:
pTeams[team]->pTeamMember[i] = 0;
To set the value of a pointer to 0 (presuming you mean point at nothing), you can do the following. Note that you can use 0 or nullptr (which is valid as of C++ 11)
int *p = nullptr;
In regards to your specific example, change
pTeams[team]->pTeamMember=0;
to
pTeams[team]->pTeamMember[index]=0;

C++ pass array argument to a function

I want to pass a reference to an array from one object GameModel to another PersonModel, store reference and then work with this array inside PersonModel just like inside GameModel, but...
I have a terrible misunderstanding of passing an array process: In the class PersonModel I want to pass an array by reference in a constructor (see code block below). But the marked line throws the compile error
PersonModel::PersonModel( int path[FieldSize::HEIGHT][FieldSize::WIDTH], int permissionLevel ) {
this->path = path; //<------ ERROR here:
//PersonModel.cpp:14:22: error: incompatible types in assignment of 'int (*)[30]' to 'int [31][30]'
this->permissionLevel = permissionLevel;
}
Here is the header file PersonModel.h
#ifndef PERSON_MODEL
#define PERSON_MODEL
#include "data/FieldSize.h"
namespace game{
class IntPosition;
class MotionDirection;
class PersonModel {
protected:
int path[FieldSize::HEIGHT][FieldSize::WIDTH];
int permissionLevel;
public:
PersonModel( int path[FieldSize::HEIGHT][FieldSize::WIDTH], int permissionLevel );
void setMotionDirection ( MotionDirection* md);
void step(long time);
void reset(long time);
};
}
#endif
As I see now, I can change the int path[FieldSize::HEIGHT][FieldSize::WIDTH]; declaration to int (*path)[FieldSize::WIDTH]; but it is much more confusing.
Help me understand this topic: what is the proper way to store the passed reference to an array to work with it later, like with usual 2D array.
UPDATE:
This array is a map of game field tiles properties represented by bit-masks, so it is read-only actually. All the incapsulated objects of GameModel class should read this array, but I definitely don't want to duplicate it or add some extra functionality.
There are no frameworks just bare Android-NDK.
I think you've fallen into the classic trap of believing someone who's told you that "arrays and pointers are the same in C".
The first thing I'd do would be to define a type for the array:
typedef int PathArray[FieldSize::HEIGHT][FieldSize::WIDTH];
You then don't need to worry about confusions between reference to array of ints vs array of references to ints.
Your PersonModel then contains a reference to one of these.
PathArray &path;
and, because its a reference it must be initialised in the constructors initialization list rather than in the constructor body.
PersonModel::PersonModel( PathArray &aPath, int aPermissionLevel ) :
path(aPath),
permissionLevel(aPermissionLevel)
{
}
Of course, holding references like this is a little scary so you might want to consider using a boost::shared_ptr or something similar instead to make the lifetime management more robust.
You cannot assign arrays as you do with value types in C++
int path[x][y] resolves to the type int (*)[y]
Possible solutions are:
Using memcpy/copy
Using std::array
You can't assign to an array like that. However you can use the fact that an array is a contiguous memory area, even when having an array of arrays, and use e.g. memcpy to copy the array:
memcpy(this->path, path, FieldSize::HEIGHT * FieldSize::WIDTH * sizeof(int));
You would have to pass a pointer to the 2d-array as you cannot pass the array as you have stated in the code snippet.
I would suggest using the STL array type. Admittedly std::array is C++ '11 standard and therefore old compiler may not support it. You can also use vector which has been around longer.
vector<vector<int>>path;
You will have to resize the 2d-vector in the constructor.
Indexing would look a bit funny:
path[1].[1] ....
With vectors, you can then pass it by reference.
the name of the array is a pointer on first element
so,
you can try
PersonModel( int (*path)[FieldSize::HEIGHT][FieldSize::WIDTH], int permissionLevel );
In C++ '=' implemented for primitive types like int and double but not for array(array is not a primitive type), so you should never use '=' to assign an array to new array, instead you should use something as memcpy to copy array. memcpy copy a memory over another memory, so you can use it to copy an array over another array:
// memcpy( dst, src, size );
memcpy( this->path, path, FieldSize::HEIGHT * FieldSize * WEIGHT * sizeof(int) );

Getting Error when trying to pass an array of object to a function

I am trying to pass an array of Student
into the function processStudent(string myFilename, Student* myArray, int &mySize).
But it is giving me different kind of errors.
The Student() does nothing, but I tried to assign them some sort of value, it still give the exact same error message:
In the main I have this:
// Create an array of students, with the size of theMax (256)
Student* arrayOfStudent= new Student[theMax];
// An integer that will keep track of actually how many students
// Because when we loop, we want to loop within the cell
// that actually have data or student.
int actualSize = 0;
// Invoke the helper function to set up the array of students
// It passed the arryOfStudent by reference, so the changes
// inside of the function will be reflected when it returns
processStudent(filename, arrayOfStudent, actualSize);
The function is like this:
void processStudent(string myFilename, Student* myArray, int& mySize)
{
// Something here, but removed still gives that error
}
// In the class Student's cpp file
Student::Student()
{
// Nothing here
}
Error Message:
new-host-2:csci135p1 george$ g++ -Wall -o csci135p2main csci135p2main.cpp
Undefined symbols for architecture x86_64:
"Student::Student()", referenced from:
_main in cc3fTXti.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
I have been stripping and stripping down my code, but this error just won't go away. I want to create this array, and pass it to the processStudent function, so it can set up each one when reading the file.
You should ask yourself some questions that could help you:
"How do I create new instance of Student?"
Well, I do it like this: Student* s = new Student(); - it creates new object and stores the referrence to it as a pointer (Student*)
"So how do I create an array of 10 Students?"
Well, it's probably going to be an array of pointers to new Students and I will probably have to call new more than once... by thinking this way you would easily end up with something like this:
Student** students = new Student*[10];
for (int i = 0; i < 10; ++i)
students[i] = new Student();
... which means, that when you clean it up, you will have to call delete on every Student* plus you'll have to clean up the array itself: call delete[] on Student** - and when you realize the ugly memory management connect with array of pointers, it should make you look for simpler and better ways of implementing it, thus you should end up using std::vector instead of array, objects instead of pointers if it's possible and if it's not, then use smart pointers rather than naked pointers at least.
The first error (which seems to have been removed from the question since I wrote this) is telling you that the second parameter of processStudent is a pointer-to-pointer, Student**, and not a pointer, Student*. That's odd since you show your declaration with a Student* parameter; are you sure that's the actual declaration from your code? Do you have a different declaration somewhere?
The second error is probably because you're not linking with the unit that contains the definition of the constructor. You're calling the compiler with just one source file (csci135p2main.cpp), and I'm guessing that you define the constructor in a different source file.
There error message is telling you the answer:
Student*’ to ‘Student**’
Change the type of the myArray argument in processStudent():
void processStudent(string myFilename, Student** myArray, int& mySize)
{
}
When an array is passed to a function it decays to a pointer:
void some_func(char* b) {...}
char buf[100];
some_func(buf);
When you pass the arrayOfStudent the array decays to a pointer, it just happens to be that the array is an array of pointers hence the **.
The linker is complaining that it cannot locate the definition of the default constructor for Student. The definition is contained in the Student.cpp file so compile all of the source files to resolve the linker error:
g++ -Wall -o csci135p2main csci135p2main.cpp Student.cpp
you'd better use a vector of Student (prefer using arrays only with basic types (int, char..) and vectors for everything else).
#include <vector>
std::vector<Student*> arrayOfStudent = new vector<Student*>();
/* ... */
processStudent(filename, arrayOfStudent, actualSize);
and
void processStudent(std::string& filename, vector<Student*>& arrayOfStudent, int& actualSize) {
/* ... */
}
I'm not sure whether that would solve your problem, but at least that's a better use...
Your code is bug-prone hard-to-maintain exception-unsafe C++.
In modern C++, you should use std::vector<Student>, with Student class implementing move semantics, or vector<shared_ptr<Student>> or vector<unique_ptr<Student>> based on the ownership (shared or not) of your Student instances.
And your function prototype should be like this if student array is an input/output parameter:
void processStudent(const std::string & filename, std::vector<Student> & students);
Instead, if the processStudent function creates the array of students (e.g. based on the content of file), just return it as a return value (this is very efficient thanks to move semantics):
std::vector<Student> processStudent(const std::string & filename);

Syntax for pointer to portion of multi-dimensional statically-allocated array

Okay, I have a multi-dimensional array which is statically-allocated. I'd very much like to get a pointer to a portion of it and use that pointer to access the rest of it. Basically, I'd like to be able to do something like this:
#include <stdio.h>
#include <string.h>
#define DIM1 4
#define DIM2 4
#define DIM3 8
#define DIM4 64
static char theArray[DIM1][DIM2][DIM3][DIM4] = {0};
int main()
{
strcpy(theArray[0][0][0], "hello world");
char** ptr = theArray[0][0];
printf("%s\n", ptr[0]);
return 0;
}s
This code results in this error using gcc:
t.c: In function ‘main’:
t.c:17: warning: initialization from incompatible pointer type
char** is apparently not the correct type to use here. I assume it's because statically-allocated arrays are created as a single block in memory while dynamically allocated ones are separated in memory, with each dimension having a pointer to the next one.
However, as you likely noticed, the number of dimensions here is painfully large, and I'm obviously going to need to use actual variables to index the array rather than the nice, slim character 0, so it's going to get painfully long to index the array in actual code. I'd very much like to have a pointer into the array to use so that accessing the array is much less painful. But I can't figure out the correct syntax - if there even is any. So, any help would be appreciated. Thanks.
theArray[0][0] gets rid of the first two dimensions, so you have something of type char [DIM3][DIM4]. The first dimension will drop out when the array decays to a pointer, so the declaration you want is:
char (*ptr)[DIM4] = theArray[0][0];
For what it's worth, gcc also displays a warning for your array declaration: "warning: missing braces around initializer". Static variables and global variables will automatically be initialized to 0, so you can fix the warning by getting rid of the initializer:
static char theArray[DIM1][DIM2][DIM3][DIM4];
Given a declaration
T arr[J][K][L][M];
the following all hold:
Expression Type Decays to
---------- ---- ---------
arr T [J][K][L][M] T (*)[K][L][M]
&arr T (*)[J][K][L][M]
arr[j] T [K][L][M] T (*)[L][M]
&arr[j] T (*)[K][L][M]
arr[j][k] T [L][M] T (*)[M];
&arr[j][k] T (*)[L][M]
arr[j][k][l] T [M] T *
&arr[j][k][l] T (*)[M]
So, in your case, the type of ptr needs to be char (*)[DIM4].
If you are using Visual Studio, a nice way to find out the type of the expression is to use typeid.
cout << typeid(&theArray[0][0]).name();
which prints
char (*)[8][64]
But note that output of typeid().name() is an implementation specific behavior and as such can not be relied upon. But VS happens to be nice in this regards by printing a more meaningful name
Does not matter that it is static, your types don't match
Why a double pointer can't be used as a 2D array?
This is a good example, although the compiler may not complain,
it is wrong to declare: "int **mat" and then use "mat" as a 2D array.
These are two very different data-types and using them you access
different locations in memory. On a good machine (e.g. VAX/VMS) this
mistake aborts the program with a "memory access violation" error.
This mistake is common because it is easy to forget that the decay
convention mustn't be applied recursively (more than once) to the
same array, so a 2D array is NOT equivalent to a double pointer.
A "pointer to pointer of T" can't serve as a "2D array of T".
The 2D array is "equivalent" to a "pointer to row of T", and this
is very different from "pointer to pointer of T".
When a double pointer that points to the first element of an array,
is used with subscript notation "ptr[0][0]", it is fully dereferenced
two times (see rule #5). After two full dereferencings the resulting
object will have an address equal to whatever value was found INSIDE
the first element of the array. Since the first element contains
our data, we would have wild memory accesses.
...
etc....
http://www.ibiblio.org/pub/languages/fortran/append-c.html

C++ string.compare()

I'm building a comparator for an assignment, and I'm pulling my hair out because this seems to simple, but I can't figure it out.
This function is giving me trouble:
int compare(Word *a, Word *b)
{
string *aTerm = a->getString();
string *bTerm = b->getString();
return aTerm->compare(bTerm);
}
Word::getString returns a string*
Error:
In member function `virtual int CompWordByAlpha::compare(Word*, Word*)':
no matching function for call to...
...followed by a bunch of function definitions.
Any help?
You're comparing a string to a string pointer, and that's not valid. You want
return aTerm->compare(*bTerm);
You aren't getting the different uses of the * operator. The use of the * in "string* bTerm = b->getString()" means "bTerm is a pointer to a string". The use of the * inside of compare(*bTerm) means "take the value of the location pointed to by bTerm" instead of just using compare(bTerm) which simply attempts to compare the value of bTerm itself, which is a hex address.
This is also happening on the left side of that call:
aTerm->compare(*bTerm); //this statement
(*aTerm).compare(*bTerm); //is the same as this statement
The -> operator just reduces the amount of typing required.
P.S.: This kind of stuff you could have easily figured out from Google or your programming textbook. Although others may disagree, I don't feel that questions about completely basic syntax have any place on Stack Overflow.