Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am trying to build a dynamic array of objects using pointers arithmetic. However, the compiler return the following error in this line in the main.cpp
(*(lista+n))(id1,seleccion1,edad1,camiseta1);
error: no match for call to '(jugador) (int &, int & short, short int &, short int &)'
any suggestion is welcome, thanks.
This is the class.
class jugador
{
private:
int id;
short seleccion;
short edad;
short camiseta;
public:
jugador();
jugador(int ID, short SELECCION, short EDAD, short CAMISETA);
int obtener_id();
short obtener_seleccion();
short obtener_edad();
short obtener_camiseta();
void cambiar_id(int nueva_id);
void cambiar_seleccion(short nueva_seleccion);
void cambiar_edad(short nueva_edad);
void cambiar_camiseta(short nueva_edad);
void cambiar_todo(int nueva_ID, short nueva_SELECCION, short nueva_EDAD, short nueva_CAMISETA);
void mostrar_jugador();
};
The constructors...
jugador::jugador()
{
id=999999;
seleccion=32;
edad=99;
camiseta=99;
}
jugador::jugador(int ID, short SELECCION, short EDAD, short CAMISETA)
{
id=ID;
seleccion=SELECCION;
edad=EDAD;
camiseta=CAMISETA;
}
Here is the full code.
Is there a special reason you are not using std::vector<jugador> Check this thread for the advantages of replacing realloc with vector
You have not given enough information so here is what I can tell from the looks of the error:
(*(lista+n))(id1,seleccion1,edad1,camiseta1);
that is NOT a function pointer, it's not even pointing to a function in the first place.
It seems like you are trying to construct an array of jugador by moving the lista pointer. If that is what you want to do then you can do late initialization.
jugador * lista; //< unitialized pointer
int n = 11; //< your number of players, lets suppose 11
lista = new jugador[11]; // now you have an array of jugadores
for(int i = 0; i != n; ++i)
{
lista[i] = jugador(id1,seleccion1,edad1,camiseta1);
}
// use your jugadores, let's suppose you want to use the tenth jugador
jugador *iterator = lista;
iterator+10;
use(*iterator); //*iterator variable holds your 10th jugador object
delete[] lista;
You are using realloc in your code, I suggest you try new and delete instead. Or else provide an explanation of why using realloc is a good choice.
Another thing I noticed in your code is that you don't free the memory you are using. Thus you have a memory leak.
If you need more jugador the use std::copy to achieve that
// let's say in this point you need 20 jugador more
jugador * newlista = new jugador[n+20];
std::copy(lista, lista+11, newlista);
delete[] lista; //you delete the old buffer
for(int i = 11; i != n+20; ++i)
{
newlista[i] = jugador(id1,seleccion1,edad1,camiseta1);
}
// and now newlista has your jugadores, you can even make a function that does that
delete[] newlista ; // delete your jugadores
I am completely agreed with Claudiordgz's response. However, if you want to call the constructor with parameters (without making extra copies) you will need to make an array of pointers instead of an array of objects. I am pasting a version of your code with that. However, I still think that a version using vectors is safer and superior.
Code:
int main()
{
int id1;
short seleccion1, edad1, camiseta1;
jugador arreglo[5];
int n = 0, i;
char opcion = 's';
jugador **lista=NULL;
while (opcion == 's')
{
lista = new jugador*[n];
cout<<"id: "<<endl;
cin>>id1;
cout<<"Seleccion: "<<endl;
cin>>seleccion1;
cout<<"Edad: "<<endl;
cin>>edad1;
cout<<"Camiseta: "<<endl;
cin>>camiseta1;
lista[n] = new jugador(id1,seleccion1,edad1,camiseta1);
n++;
cout << "Desea ingresar otro elemento? (s/n): ";
cin >> opcion;
}
cout << "\nArreglo completo\n";
for (i=0; i<n; i++)
{
lista[n].mostrar_jugador();
}
//deallocating memory
for (int i=0; i<n; i++)
{
delete jugador[i];
}
delete [] jugador;
return 0;
}
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 12 months ago.
Improve this question
I want to implement a dynamic array as a class.
I haven written a method which adds an element at the end of the array:
void DynamicArray::addElementAtEnd() {
cout << "\nPodaj liczbe calkowita: ";
int* number = new int;
cin >> *number;
if (DynamicArray::array == NULL) {
DynamicArray::array = new int[1];
DynamicArray::array[0] = *number;
delete number;
(*DynamicArray::size)++;
return;
}
int* buff = new int[*DynamicArray::size + 1];
memcpy(buff, DynamicArray::array, (*DynamicArray::size) * sizeof(int));
delete[] DynamicArray::array;
buff[(*DynamicArray::size)] = *number;
DynamicArray::array = buff;
(*DynamicArray::size)++;
delete number;
return;
};
Here's the .h file of the DynamicArray class:
#include <iostream>
using namespace std;
class DynamicArray {
public:
int* array;
int* size;
public:
DynamicArray() {
DynamicArray::size = new int;
*DynamicArray::size = 0;
};
void handleMenu();
void readFromFile();
void addElementAtEnd();
void addElementAtBeginning();
void addAtIndex(int index);
void deleteElementAtEnd();
void deleteElementAtBeginning();
void deleteElementByIndex(int index);
void showAllElements();
void showElementAtIndex(int index);
void findElementByValue(int value);
};
The problem is that this method adds only the first element, but if I try to add more then nothing happens. I debugged it, and the problem starts on this line:
int* buff = new int[*DynamicArray::size + 1];
I don't know why, but it seems like this line is not creating a bigger array.
I searched for some solutions, and it seems that the problem is connected with using *DynamicArray::size + 1 instead of eg a variable, or I don't do something right with it.
The actual problem is that you are not initializing array to NULL.
So when you check if array is NULL on the first iteration, it is often not.
The minimal solution:
DynamicArray::DynamicArray() {
this->size = 0; // You should use 'size' like an int, not a pointer
this->array = NULL;
}
// Or using the Member Initializer List (by #user4581301)
DynamicArray::DynamicArray(): size(0), array(nullptr) {}
Note: Differences between NULL and nullptr
Other simple solution could be to check if size is equal to 0 instead of checking if array is NULL.
The above change will solve your problem but your code can still be improved.
Take into account the comments of other users.
And make sure to free each dynamically allocated memory.
Let's address a variety of things.
class DynamicArray {
public:
int* array;
int* size;
public:
DynamicArray() {
DynamicArray::size = new int;
*DynamicArray::size = 0;
}
};
A few things here. First, as others have suggested, there's zero reason to make size a pointer.
Next, it's a strong guideline / good idea to always initialize your fields when declared.
So this section of code can look like this:
class DynamicArray {
public:
int* array = nullptr;
int size = 0;
public:
DynamicArray() {
}
};
After that, please use nullptr instead of NULL. NULL is from C, but the correct value in C++ is nullptr.
Now, let's look at this bit of code.
void DynamicArray::addElementAtEnd() {
cout << "\nPodaj liczbe calkowita: ";
int* number = new int;
cin >> *number;
if (DynamicArray::array == NULL) {
DynamicArray::array = new int[1];
DynamicArray::array[0] = *number;
delete number;
(*DynamicArray::size)++;
return;
}
int* buff = new int[*DynamicArray::size + 1];
memcpy(buff, DynamicArray::array, (*DynamicArray::size) * sizeof(int));
delete[] DynamicArray::array;
buff[(*DynamicArray::size)] = *number;
DynamicArray::array = buff;
(*DynamicArray::size)++;
delete number;
return;
};
Aside from the extra colon on the end of the function (entirely not necessary), this is far more complicated than it needs to be. First, get rid of the int pointer. That's just ridiculous.
void DynamicArray::addElementAtEnd() {
cout << "\nPodaj liczbe calkowita: ";
int number = 0;
cin >> number;
int * newArray = new int[size + 1];
newArray[size] = number;
if (array != nullptr) {
for (int index = 0; index < size; ++index) {
newArray[index] = array[index];
}
delete [] array;
}
array = newArray;
++size;
}
A last comment -- it would make far more sense to pass in the new value as an argument to the method, and the calling test code should get the value you're adding. But you're just learning, so this works.
Note also that you shouldn't specify the class the way you have: DynamicArray::array. No one does that. Do it the way I did above.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
Im building this subnet calculator but now im stuck, with array. I want to create new int function that will return array, but I don't know how I tried many things but still don't have idea, think it will have to do something with pointers. I want to create new function starting at "while(octet4>0)". so octet4 gets passed into function and function should return fully functional array which I can use then in main. Hope somebody will know answer for what im looking for, hope solution would not be too complicated because Im just learning programming and thought this would be fun project to take on.
int main() {
int i=0,j,q,s,size=8,temp;
int binary_ip[8];
int netmask;
int mask;
int octet1, octet2, octet3, octet4;
string ip;
cout<<"Vnesite IP naslov, npr. 192.168.32.55:"<<endl;
cin>>ip;
cout<<"Vnesite netmasko, npr. /27:"<<endl;
cin>>netmask;
stringstream stream(ip);
char ch;
stream >> octet1 >> ch >> octet2 >> ch >> octet3 >> ch >> octet4;
while(octet4>0){
binary_ip[i]=octet4%2;
i++;
octet4=octet4/2;
}
switch(i){
case 7:binary_ip[7]=0;
break;
case 6:for(s=6;s<=7;s++)binary_ip[s]=0;
break;
case 5:for(s=5;s<=7;s++)binary_ip[s]=0;
break;
case 4:for(s=4;s<=7;s++)binary_ip[s]=0;
break;
case 3:for(s=3;s<=7;s++)binary_ip[s]=0;
break;
case 2:for(s=2;s<=7;s++)binary_ip[s]=0;
break;
case 1:for(s=1;s<=7;s++)binary_ip[s]=0;
break;
}
for(q=0;q<size/2;q++){
temp=binary_ip[size-1-q];
binary_ip[size-1-q]=binary_ip[q];
binary_ip[q]=temp;}
return 0;
}
Some options:
Use std::array instead of a regular C array. Those are easier to work with and you are already using standard library. http://www.learncpp.com/cpp-tutorial/6-15-an-introduction-to-stdarray/
Have your function fill-in the array, rather than create and return it:
void MakeArray(int octet4, int binary_ip[8]) ;
Use pointers, allocate array with "new" and free it with "delete". You'll need a way to know the size of the array, however.
#include <iostream>
int array(int octet4, int binary_ip[]);
int main()
{
int binary_ip[6];
int octet4 = 55;
int i = 0;
i = array(octet4, binary_ip);//binary_ip passes in the address of the first element in the array
}
int array(int octet4, int binary_ip[])
{
int i = 0;
while(octet4>0)
{
binary_ip[i]=octet4%2;
i++;
octet4=octet4/2;
}
return i;
}
or you can use a vector like Daniel H suggested
void array(int octet4, std::vector<int> &binary_ip)
{
while(octet4>0)
{
binary_ip.push_back(octet4%2);
octet4=octet4/2;
}
}
int main()
{
std::vector<int> binary_ip;
int octet4 = 55;
array(octet4, binary_ip);
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am doing my c++ homework on an online judge. There are m strings with a length of n. I need to find the minimal expression of a new string, and then insert it in an trie tree. For each string, I need to return the "positon number" of the first identical string.
Following is my code:
#include <cstdio>
using namespace std;
struct trie_node
{
trie_node * firstSon;
trie_node * nextBro;
char value;
bool isKey;
int firstPos;
trie_node(char value):firstSon(NULL), nextBro(NULL), value(value), isKey(false), firstPos(-1){}
};
class trie_Tree
{
public:
trie_Tree();
int searchStr(char* desStr, int len, int selfPos);
private:
trie_node* searchChar(trie_node* fatherNode, char desChar);
trie_node* root;
};
trie_Tree::trie_Tree()
{
root = new trie_node('0');
}
int trie_Tree::searchStr(char * desStr, int len, int selfPos)
{
trie_node* fatherNode = root;
for (int i=0; i<len; i++)
{
fatherNode = searchChar(fatherNode, desStr[i]);
}
if (!fatherNode->isKey)
{
fatherNode->isKey=true;
fatherNode->firstPos=selfPos;
}
return fatherNode->firstPos;
}
trie_node* trie_Tree::searchChar(trie_node* fatherNode, char desChar)
{
if (fatherNode->firstSon==NULL)
{
fatherNode->firstSon = new trie_node(desChar);
return fatherNode->firstSon;
}
trie_node* travNode = fatherNode->firstSon;
while (travNode->nextBro!=NULL)
{
if (travNode->value==desChar) return travNode;
travNode=travNode->nextBro;
}
if (travNode->value==desChar) return travNode;
else
{
travNode->nextBro = new trie_node(desChar);
return travNode->nextBro;
}
}
char* getMinPre(char *s, int _size)
{
int min=0, trav=1;
while (trav<_size && min<_size)
{
int i;
for (i=0; i<_size; i++)
{
if (s[(min+i)%_size]<s[(trav+i)%_size])
{
trav=trav+i+1;
break;
}
else if (s[(min+i)%_size]>s[(trav+i)%_size])
{
min=trav;
trav=trav+1;
break;
}
}
if (i==_size) break;
}
char * result=new char[_size];
for (int i=0; i<_size; i++)
{
result[i]=s[(min+i)%_size];
}
return result;
}
int main()
{
int m, n, result=0;
scanf("%d %d", &m, &n);
trie_Tree tt=trie_Tree();
char* s=new char[n+1];
for (int i=0; i<m; i++)
{
scanf("%s", s);
s=getMinPre(s, n);
result = tt.searchStr(s, n, i);
printf("%d\n", result);
}
delete[] s;
return 0;
}
I compiled my code with VS and g++, and runned my program lots of times for testing. It worked perfectly.
But when the online judge system returned runtime error(exitcode 6).
I googled "exit code 6". It is raised by the program itself, e.g. by making the abort() system call. It can be caused by new and delete operation. But I still cannot debug my code.
Anyone can help me?
That's a lot of code, but some things to look into:
Inside your main function you allocate s: char* s=new char[n+1];.
You pass s into char* getMinPre(char *s, int _size).
getMinPre allocates another buffer, and returns it, overwriting s: s=getMinPre(s, n); (memory leak of initial s buffer).
This potentially happens a lot in the main function's loop, hence you may run out of memory. (getMinPre allocating and overwriting the pointer to allocated buffer).
Since this is an online judge platform, I'd recommend coming up with extreme test cases (min, max elements, tons of iterations) and running them locally.
Also: add some debug information. You can even encapsulate them within #ifdef so you won't have to remove them.
In your trie_Tree constructor, you use new to allocate dynamic memory, but I don't find you delete that object anywhere. Similarly, in searchChar, you allocate a lot of son nodes but never delete them. Also in getMinPre. All of them will lead to memory leak. The only memory you freed is the result in main().
In C++, dynamic memory management is a really complex topic and error prone, every time you allocate some memory with new, you need to keep in mind deallocate them with delete somewhere. Like in C, every time you use malloc(), you need free().
There are a lot of libraries you can use instead of managing the memory yourself. For a linked list, you may consider std::vector in header<vector>.
BTW, I think this code looks like C with Class, not C++.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
EDIT (Remake): Here's what I'm trying to do:
char* someArray = new char[someIntVariable];
And then loop over the array and use a custom function to get the contents of the other array (that's where the problem lies):
char* temp = someFunc(someArray, someIntVariable); //someFunc is a char* returning function
for(int i = 0; i < someIntVariable; i++){
someArray[i] = temp[i] //temp[i] is where the problem lies. It returns something like: /213
}
Text version: I'm trying to get a pointer to a char array to return all of the arrays contents (only using one single pointer) and loop over a previously created array and fill it's spaces or somehow assign it one single assignment.
Hope this is comprehensible.
"someFunc":
char* convertCharArr(char* _inputArr, int arrSize){
char *inputArr = new char[arrSize];
std::memmove(inputArr, _inputArr, sizeof(*inputArr));
static char *resizedUsrInptAns = new char[arrSize];
for(int i = 0; i < sizeof(inputArr)/sizeof(inputArr[0]); i++){
if(i == arrSize + 1){
break;
}
resizedUsrInptAns[i] = inputArr[i];
}
return resizedUsrInptAns;
}
ptr2 and ptr1 are equivalent, so I am going to ignore ptr2 for my answer.
If you want to clone a char array of unknown size, you have to use dynamic memory allocation:
char * p = malloc(strlen(ptr1) + 1);
strcpy(p, ptr1);
// ...
free(p);
You can't assign a pointer to an array, thats impossible in c. You can only do the opposite, assigning an array to a pointer.
You will have to create a new array(with dynamic allocation) and copy the data into that array.
Example
char* pChar = GetArrayPointer();
char* pNewArrayPointer = (char*)malloc(strlen(pChar) + 1);
strcpy(pNewArrayPointer, pChar);
Edit
1) You don't have to copy _inputArr because you don't write data to it in converCharArr().
2) Why are you using sizeof(inputArr)/sizeof(inputArr[0]), it doesn't works, because inputArr is a pointer(well, there are some differences between pointers and arrays :)). You should use arrSize.
Array and pointer differences : http://www.geeksforgeeks.org/g-fact-5/
In your example both prt1 as well as ptr2 are pointing to same char. And you can get same effects for ptr1/ptr2 using cout what you get for arr1.
So, below all will print same thing:-
cout << arr1;
cout << ptr1;
cout << ptr2;
If you want to create new array using ptr2 with same contents as of arr1, then
ptr2 = malloc(strlen(ptr1) + 1);
strcpy(ptr2, ptr1);
May this would help
link: http://ideone.com/Nwqd22
#include <iostream>
using namespace std;
char* fun(){
char * returnValue = "String";
return returnValue;
}
int main() {
char * firstVariable;
firstVariable = fun();
cout << firstVariable;
return 0;
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I just came from C to C++ and find difficulties with compare string method.
I have a simple task. I need to create a class of school Teachers, then make an object array, and after withdrow all Teachers, who's subject is similar to testSubject.
So here is my class
class Teacher
{
private:
string FamilyName;
string Name;
string Patronymic;
string sex;
int exp;
std::string subject;
string speciality;
int age;
public:
Teacher();
int getExp();
string getSubject();
int getAge();
void show();
};
And here is my func, that withdrow the list of Teachers, teaching the input subject
void ListTeacherSub (Teacher spis[], int n)
{
//List of teachers, who's subject is like testSubject
std::string testSubject;
cout<<"Enter test subject "; cin>>testSubject;
for (int i=0; i<n; i++)
{
if (spis[n].getSubject().compare(testSubject) == 0)
spis[i].show();
}
}
Here it is main() function
int main()
{
Teacher *spis;
int n;
cout<<"Enter numbers of student "; cin>>n;
spis = new Teacher[n];
for (int i=0; i<n; i++)
{
spis[i].show();
}
ListTeacherAge(spis, n);
ListTeacherEx(spis, n);
ListTeacherSub(spis, n);
delete[] spis;
return 0;
}
So, everything is working nice, but when program reaches ListTeacherSub(spis, n) it is stops working. I used to work with strcmp only, but it doesn't works with string, as I understood.
So I decided to look for different realizations, and found that one http://www.cplusplus.com/reference/string/string/compare/
How can i fix my problem?
This
if (spis[n].getSubject().compare(testSubject) == 0)
should be
if (spis[i].getSubject().compare(testSubject) == 0)
This is incorrect (and causes undefined behaviour as it going beyond the end of the array):
if (spis[n].getSubject().compare(testSubject) == 0)
as it using n and not the loop counter i.
Other:
always check the result of input operations to ensure variables have been correctly populated and subsequent code is not using uninitialised or stale values:
if (std::cin >> n)
{
spis = new Teacher[n];
}
prefer to avoid explicit dynamic memory management. In this case std::vector<Teacher> would be suitable:
if (std::cin >> n)
{
std::vector<Teacher> spis(n);
for (Teacher& t) t.show();
}
Pass spis by const Teacher& to functions to avoid copy (and the parameter n is now superfluous).
std::string instances can be compared using ==.