(I'm not posting my code as this is for a project, however I have tried to get help for this issue but have had no luck)
Hi there, I am trying to initialise the size of an array of pointers (char*) which is a private member variable of my class class A
I'm using the constructor to set the size by setting an integer variable (also a member variable) which will then be used to create my array of pointers.
I have done this so far:
// Constructor - 'int value' is set to a value
private:
int value;
char ** myArray = new char*[value];
So basically I want an array of pointers in which each element can point to a string. I am passing string variables to myArray by using (char*) stringVar.c_str();
Although all of this works, I am getting some pretty weird errors when trying to store variables and have even gotten this error:
free (): invalid next size (fast)
It's weird because even when myArray is of size 4, when I try to access, say, the 3rd element, I get the same error as above.
I am very new to C++ and am very intent on solving these issues. I've had to resort to this forum for help and am looking forward to some ideas from you guys :)
if you are new C++ programmer and want work with C++ String list is better work with std::vector<std::string> for complete tutorial of how using vectors see:
http://www.cplusplus.com/reference/vector/vector/
but in you question is String list size fixed?or not?
if string list is not fixed you must malloc space for array first time in constructor and then realloc array when you want insert a string in your string list for example:
class A{
private:
char** arrayy;
int arrayysize;
A(){
arrayy = (char**)calloc(1,sizeof(char*));
arrayysize = 1;
}
insertToarrayy(char* data){
strcpy(arrayy[arrayysize-1],data);
arrayy = (char**)realloc(arrayy,arrayysize+1);
arrayysize += 1;
}
}
Related
I'm trying to allocate a new array if integers (See HwGrades allocation below)
When I put the HwNum=2, the new function creates an array of size 1 only!
and when the for loop iterates 2 times it doesnt give me access violation
Help would be appreciated..
Here's the constructor
EE_Course::EE_Course(int Course_ID, char * Course_Name, int Hw_Num, double Hw_Weigh,int Factor_)
{
CourseID = Course_ID;
CourseName = new char[strlen(Course_Name) + 1];
strcpy(CourseName, Course_Name);
HwNum = Hw_Num;
HwWeigh = Hw_Weigh;
HwGrades = new int [HwNum]; // STARTING FROM HERE
for (int i = 0; i < Hw_Num; i++) { //UNTIL HERE
HwGrades[i] = 0;
}
Factor_ = 0;
ExamGrade = 0;
}
And those are the Course class private variables :
protected:
int CourseID;
int HwNum;
char* CourseName;
double HwWeigh;
int ExamGrade;
int* HwGrades;
};
The debugger does not show the whole array if it is a pointer. It shows the address of the array and the first element the array is pointing. So there is nothing wrong with your code.
You could see it if it was defined as an array:
int HwGrades[100];
If you really want to use a pointer and see it's content, you have two choices:
Define it as an array, debug it, fix/verify your code and turn back to pointer.
I don't know what is you environment, but usually there is a memory view option. You can check what's in the array any time you want. Just open the memory view of your IDE and watch the address of your pointer.
EDIT:
Apparently there is a third(and the best) option. See Rabbi Shuki's answer.
The debugger just shows one element. Here's why:
The type of HwGrades is int*. So when showing the contents of HwGrades what should the debugger do? The debugger does not know, that the pointer is actually pointing to the first element of an array. It assumes it just points to an int. Therefore, the debugger shows just the first element of the array that is actually of size 2.
If you're using the Visual Studio debugger, you can write HwGrades,2 in the watch window to see the first two elements of the array. Replace 2 by whatever your tickles your fancy. ;)
However, generally I would strongly advice to use the STL container std::vector for dynamic arrays. It will be easier to program and the debugger will be your friend without the hassle.
If you want to see the next cells of the array in the watch screen you can put the name and add a comma and the number of cells you want to see.
I.E.
HwGrades, 2
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) );
I apologise if I'm completely misunderstanding C++ at the moment, so my question might be quite simple to solve. I'm trying to pass a character array into a function by value, create a new array of the same size and fill it with certain elements, and return that array from the function. This is the code I have so far:
char *breedMutation(char genome []){
size_t genes = sizeof(genome);
char * mutation = new char[genes];
for (size_t a = 0 ;a < genes; a++) {
mutation[a] = 'b';
}
return mutation;
}
The for loop is what updates the new array; right now, it's just dummy code, but hopefully the idea of the function is clear. When I call this function in main, however, I get an error of initializer fails to determine size of ‘mutation’. This is the code I have in main:
int main()
{
char target [] = "Das weisse leid"; //dummy message
char mutation [] = breedMutation(target);
return 0;
}
I need to learn more about pointers and character arrays, which I realise, but I'm trying to learn by example as well.
EDIT: This code, which I'm trying to modify for character arrays, is the basis for breedMutation.
int *f(size_t s){
int *ret=new int[s];
for (size_t a=0;a<s;a++)
ret[a]=a;
return ret;
}
Your error is because you can't declare mutation as a char[] and assign it the value of the char* being returned by breedMutation. If you want to do that, mutation should be declared as a char* and then deleted once you're done with it to avoid memory leaks in a real application.
Your breedMutation function, apart from dynamically allocating an array and returning it, is nothing like f. f simply creates an array of size s and fills each index in the array incrementally starting at 0. breedMutation would just fill the array with 'b' if you didn't have a logic error.
That error is that sizeof(genome); will return the size of a char*, which is generally 4 or 8 bytes on a common machine. You'll need to pass the size in as f does since arrays are demoted to pointers when passed to a function. However, with that snippet I don't see why you'd need to pass a char genome[] at all.
Also, in C++ you're better off using a container such as an std::vector or even std::array as opposed to dynamically allocated arrays (ones where you use new to create them) so that you don't have to worry about freeing them or keeping track of their size. In this case, std::string would be a good idea since it looks like you're trying to work with strings.
If you explain what exactly you're trying to do it might help us tell you how to go about your problem.
The line:
size_t genes = sizeof(genome);
will return the sizeof(char*) and not the number of elements in the genome array. You will need to pass the number of elements to the breedMutation() function:
breedMutation(target, strlen(target));
or find some other way of providing that information to the function.
Hope that helps.
EDIT: assuming it is the number of the elements in genome that you actually want.
Array are very limited.
Prefer to use std::vector (or std::string)
std::string breedMutation(std::string const& genome)
{
std::string mutation;
return mutation;
}
int main()
{
std::string target = "Das weisse leid"; //dummy message
std::string mutation = breedMutation(target);
}
Try replacing the second line of main() with:
char* mutation = breedMutation(target);
Also, don't forget to delete your mutation variable at the end.
I am trying to learn C++ on my own and was trying out this. I have a struct one of whose member is an array of another structs. I have a question about alternative notation.
The structs that I have defined are
struct employeeRecordT {
string name;
string title;
string ssnum;
double salary;
int withholding;
};
struct payrollT {
int num;
employeeRecordT *array;
} payroll;
I am allotting memory to payroll using the following construct
payroll.array = new employeeRecordT[payroll.num];
where payroll.num is indicating the number of elements in the array. I can access the element name of the employeeRecordT by using the array notation e.g.
payroll.array[i].title
I wanted to know how to access this using the pointer notation, I have tried
payroll.(array+i)->name = "Vikas";
and I get the following error message from g++
toy.cc:30:13: error: expected unqualified-id before '(' token
toy.cc:30:14: error: 'array' was not declared in this scope
I am trying to understand what I should be using and why? Could you guys help explain.
Thanks in advance.
Regards,
Vikas
(payroll.array+i)->name = "Vikas";
array is a member of payroll, so when you were doing payroll.(array+i), the bracket notation (i.e. "do this first") was trying to use a variable array, and not the one within the scope of payroll.
Of course, using C++, the better solution is Neils. Use a std::vector instead of your own dynamically allocated storage if possible.
If it hurts, don't do it. Use a std::vector of your structures instead.
I have a struc like this:
struct process {int PID;int myMemory[];};
however, when I try to use it
process p;
int memory[2];
p.myMemory = memory;
I get an criptic error from eclipse saying int[0] is not compatible with int[2];
what am i doing wrong?
Thanks!
Don't use static arrays, malloc, or even new if you're using C++. Use std::vector which will ensure correct memory management.
#include <vector>
struct Process {
int pid;
std::vector<int> myMemory;
};
Process p;
p.reserve(2); // allocates enough space on the heap to store 2 ints
p.myMemory.push_back( 4815 ); // add an index-zero element of 4815
p.myMemory.push_back( 162342 ); // add an index-one element of 162342
I might also suggest creating a constructor so that pid does not initially have an undefined value:
struct Process {
Process() : pid(-1), myMemory() {
}
int pid;
std::vector<int> myMemory;
};
I think you should declare myMemory as an int* then malloc() when you know the size of it. After this it can be used like a normal array. Int[0] seems to mean "array with no dimension specified".
EXAMPLE:
int *a; // suppose you'd like to have an array with user specified length
// get dimension (int d)
a = (int *) malloc(d * sizeof(int));
// now you can forget a is a pointer:
a[0] = 5;
a[2] = 1;
free((void *) a); // don't forget this!
All these answers about vector or whatever are confused :) using a dynamically allocated pointer opens up a memory management problem, using vector opens up a performance problem as well as making the data type a non-POD and also preventing memcpy() working.
The right answer is to use
Array<int,2>
where Array is a template the C++ committee didn't bother to put in C++99 but which is in C++0x (although I'm not sure of the name). This is an inline (no memory management or performance issues) first class array which is a wrapper around a C array. I guess Boost has something already.
In C++, array definition is almost equal to pointer constants, meaning that their address cannot be changed, while the values which they point to can be changed. That said, you cannot copy elements of an array into another by the assignment operator. You have to go through the arrays and copy the elements one by one and check for the boundary conditions yourself.
The syntax ...
struct process {int PID;int myMemory[];};
... is not valid C++, but it may be accepted by some compilers as a language extension. In particular, as I recall g++ accepts it. It's in support for the C "struct hack", which is unnecessary in C++.
In C++, if you want a variable length array in a struct, use std::vector or some other array-like class, like
#include <vector>
struct Process
{
int pid;
std::vector<int> memory;
};
By the way, it's a good idea to reserve use of UPPERCASE IDENTIFIERS for macros, so as to reduce the probability of name collisions with macros, and not make people reading the code deaf (it's shouting).
Cheers & hth.,
You cannot make the array (defined using []) to point to another array. Because the array identifier is a const pointer. You can change the value pointed by the pointer but you cannot change the pointer itself. Think of "int array[]" as "int* const array".
The only time you can do that is during initialization.
// OK
int array[] = {1, 2, 3};
// NOT OK
int array[];
array = [1, 2, 3]; // this is no good.
int x[] is normally understood as int * x.
In this case, it is not, so if you want a vector of integers of an undetermined number of positions, change your declaration to:
struct process {int PID;int * myMemory;};
You should change your initialization to:
int memory[2];
p.myMemory = new int[ 10 ];