I created a simple program to help me understand how to Dynamically Allocate a structure. I want the program to gets 5 names and 5 accounts from the user, and display the names and the accounts. I know a pointer is like a reference variable, the only differences instead of passing the value, it passes the address of the variable. I set a breaking point for line 23 ("getline(std::cin,clientPtr[count].name);"), line 25 ("std::cin.ignore(std::numeric_limits::max(),'\n');"),
line 27 ("std::cin >>clientPtr[count].accounts;"), line 40 ("std::cout <<"Name:" << clientPtr[count].name;"), line 41 ("std::cout <<"Name:" << clientPtr[count].name;"),line 31( showInfo(&client);). When I debugged it shows that line 41 is not executing. It should display the names and the accounts of each client. In this case it's not. I'm not sure why, just a little background on me, I'm new to C++, as well with using the debugger. I'm using xcode 8.2 and the debugger I am using is lldb. I'm here to learn, so anything will help. Thanks.
#include <iostream>
#include <limits>
struct BankInfo
{
std::string name;
std::string accounts;
};
void showInfo(BankInfo*);
int main()
{
BankInfo client;
BankInfo* clientPtr=nullptr;
clientPtr = new BankInfo[5];
for(int count =0; count < 5; count++)
{
std::cout << "Enter your name:";
getline(std::cin,clientPtr[count].name);
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
std::cout << "Enter you account number:";
std::cin >>clientPtr[count].accounts;
}
showInfo(&client);
return 0;
}
void showInfo(BankInfo* clientPtr)
{
for(int count =5; count < 5; count++)
{
std::cout <<"Name:" << clientPtr[count].name;
std::cout <<"Account:" << clientPtr[count].accounts;
}
}
You are handing the wrong thing to showInfo(). You have two variables.. a single BankInfo variable and a dynamic allocated array with size 5.
You want to iterate over the latter and not the former.
Changing showInfo(&client);to showInfo(clientPtr); should do the trick perhaps?
So I fixed the solution I made several mistakes, but thank you for the suggestion. Here's what I did.
#include <iostream>
#include <limits>
struct BankInfo
{
std::string name;
std::string accounts;
};
void showInfo(BankInfo*);
int main()
{
BankInfo client;
BankInfo* clientPtr=nullptr;
clientPtr = new BankInfo[5]; //Allocate an array of BankInfo struct on the heap
for(int count =0; count < 5; count++)
{
std::cout << "Enter your name:";
getline(std::cin,clientPtr[count].name); // stores the value in the name member
std::cout << "Enter you account number:";
std::cin >>clientPtr[count].accounts; // stores the value in accounts member
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
}
showInfo(clientPtr);
delete [] clientPtr;
clientPtr = nullptr;
return 0;
}
void showInfo(BankInfo* clientPtr)
{
for(int count =0; count < 5; count++)
{
std::cout <<"\nName:" << clientPtr[count].name; // dereference the pointer to the structure
std::cout <<"\nAccount:" << clientPtr[count].accounts; // dereference the pointer to the structure
}
}
for(int count=1 ; count<=5 ; count++)
{
//do your stuff here
}
Related
I'm creating a console timetable application in which you can create a timetable, change it, and delete it. I'm on the stage of taking the input for the calculator. However, when I run the code, as soon as I finish taking the input, the window just closes. Here is the code:
int input()
{
int numberOfElements;
cout << "How many items do you want in your timetable? ";
cin >> numberOfElements;
char* itemArray[numberOfElements] = {};
for (int i = 1; i <= numberOfElements; i++)
{
cout << "Please enter a session: ";
cin >> itemArray[i];
}
for (int i = 0; i < numberOfElements; i++)
{
cout << itemArray[i] << "\n";
}
return 0;
}
There is some code in the main function as well, but it's irrelevant (only to find out for what day it is). I want you to have a look at the first for loop in the code, where I take in input. When running this code (in a separate window altogether), it closes as soon as I give in the input. Even if I say that I want 3 sessions (or any number), it closes right after I input the first session. In case you were wondering, I already tried replacing
char* itemArray[numberOfElements] = {};
with
char* itemArray[numberOfElements];
Just in case it's useful to anyone, I'm using the MinGW compiler.
Thanks.
In Standard C++ the size of an array must be a compile time constant. So take for example the following statements in your program:
int numberOfElements;
cout << "How many items do you want in your timetable? ";
cin >> numberOfElements;
char* itemArray[numberOfElements] = {};//not standard C++
The statement char* itemArray[numberOfElements] = {}; is not standard C++ because numberOfElements is not a constant expression.
Additionally, you're going out of bounds of the array because of the <= in the for loop instead of <. This leads to undefined behavior.
Better would be to use std::vector<std::string> as shown below:
#include <iostream>
#include<vector>
#include <string>
int main()
{
int numberOfElements;
std::cout << "How many items do you want in your timetable? ";
std::cin >> numberOfElements;
std::vector<std::string> arr(numberOfElements); //create vector of size numberOfElements
for (std::string &element: arr)
{
std::cout << "Please enter the element: ";
std::cin >> element;
}
for (const std::string& element: arr)
{
std::cout << element << "\n";
}
}
Demo.
For a program I must use an array and not vector. I have to take in user's input, and it's a indefinite amount of them. The user can type in 5 values, or 50. I am absolutely stumped as to how to go about doing this. Using a for loop for example:
Int a[10];
Int b;
For (int i=0; i<10; i++)
{
Cout<<"enter values:";
Cin>>b;
A[i]=b;
}
With this I can take an array of 10 of user defined variables but how would I go about making it a dynamic size? Thank you for the help!
The size of a static array must be known at compile time, otherwise you must use a dynamic array. For example
#include <iostream>
int main()
{
// Determine how many total entries are expected
int entries;
std::cout << "How many values do you want to enter?" << std::endl;
std::cin >> entries;
// Allocate a dynamic array of the requested size
int* a = new int[entries];
// Populate the array
for (int i = 0; i < entries; ++i)
{
std::cout << "enter a value: ";
std::cin >> a[i];
std::cout << std::endl;
}
// Clean up your allocated memory
delete[] a;
return 0;
}
Ok, so my pointer logic is a little flawed, but I'm working on it. My problem is in the main.cpp file below, Inside the getStructData() function. I have the questions listed down there in comments, and what I think seems right, but know it's not. I will now put the question up here, out of the comments.
I have a function getMyStructData(), I can currently print out the elements of a specific struct based on an index number. Instead I'd like to copy the elements of that struct at the given index number (int structureArrayIndex) from the private structure into the structure of the pointer argument.
Inside myStructure.h
struct myStructure
{
int myInteger;
double myDoublesArray[5];
char myCharArray[80];
};
Inside myClass.h
#include "myStructure.h"
class myClass
{
private:
myStructure myStruct[5]
private:
Prog1Class();
~Prog1Class();
void setMyStructData();
void getMyStructData(int structureArrayIndex, struct myStructure *info);
};
Inside main.cpp
#include<iostream>
#include <string>
#include "myClass.h"
#include "myStructure.h"
using namespace std;
void myClass::setMyStructData()
{
for(int i = 0; i < 5 ; i++)
{
cout << "Please enter an integer: " << endl;
cin >> myStruct[i].myInteger;
for(int j = 0; j< 5; j++)
{
cout << "Please enter a double: ";
cin >> myStruct[i].myDoublesArray[j];
}
cout << endl << "Please enter a string: ";
cin.ignore(256, '\n');
cin.getline(myStruct[i].myCharArray, 80, '\n');
}
}
void Prog1Class::getStructData(int structureArrayIndex, struct myStructure *info)
{
//****Below I have what's working, but Instead of just printing out the elements, what I want to do is copy the elements of that struct at the given index number (int structureArrayIndex) from that private structure into the structure of the pointer argument.
//I'm guessing something like this:
// info = &myStructure[structureArrayIndex];
//I know that's wrong, but that's where I'm stuck.
//****Here is how I would print out all of the data using the int structureArrayIndex
cout << myStruct[structureArrayIndex].myInteger << endl;
for (int k = 0; k < 5; k++)
{
cout << myStruct[structureArrayIndex].myDoublesArray[k] << endl;
}
cout << myStruct[structureArrayIndex].myCharArray << endl;
}
int main(void)
{
myClass c;
c.setMyStructData();
c.getStructData(1);
cin.get();
}
In your commented code, you are assigning pointers and not an actual copy of the data.
To do what you ask with the code you provided you may do:
// Check that info isn't null
if (!info) {
return;
}
// Simple copy assignment of private structure to info.
*info = myStruct[structureArrayIndex];
This dereferences the pointer info and does a default copy operation of the myStructure type in myStruct array at the structureArrayIndex.
You have to assign content of myStruct[structureArrayIndex] to content of info.
*info = myStruct[structureArrayIndex];
I'm working on an assignment that is introducing the principals of dynamic allocation of memory and pointers. I had made a simple program in the past that accepted 5 names and 5 scores and then used a selection sort to put them in descending order. My assignment now is to come back to that same program and ask the user how many scores they would like to input, then use pointers to dynamically allocate the necessary amount of memory. This is my first time working with pointers and these concepts so im still trying to figure it all out.
I got the code to compile but I get a segmentation fault error as soon as i enter any integer number for how many scores i would like to input (which is the first thing the program asks)
Im sure there are a few errors along the way with how i called and declared functions so if theres anything i just desperately change please let me know, but for now I dont understand why my program is crashing where it is crashing.
Here is my code
#include <iostream>
using namespace std;
void initializeData(string *names[], int *scores[], int num);
void displayData(string *names[], int *scores[], int num);
void sortData(string *names[], int *scores[], int num);
int main()
{
int num;
int **intPoint;
string **strPoint;
cout << "How many scores would you like to enter?: ";
cin >> num;
cout << " core dumped? ";
*intPoint = new int[num];
*strPoint = new string[num];
initializeData(strPoint,intPoint,num);
sortData(strPoint,intPoint,num);
displayData(strPoint,intPoint,num);
return 0;
}
void initializeData(string *names[], int *scores[], int num)
{
for(int i=0;i<num;i++)
{
cout << "Please input the name for score: " << i+1 << ": " << endl;
cin >> *(names[i]);
cout << "Please input the score for player: " << i+1 << ": " << endl;
cin >> *(scores[i]);
}
}
void sortData(string *names[], int *scores[], int num)
{
int minIndex,minValue,x;
string stringTemp;
for(int i = 0;i<(num-1);i++)
{
minIndex = i;
minValue = *(scores[i]);
for(x= i+1;x<num;x++)
{
if(*(scores[x]) > minValue)
{
minValue = *(scores[x]);
minIndex = x;
}
}
*(scores[minIndex])=*(scores[i]);
*(scores[i]) = minValue;
stringTemp = *(names[minIndex]);
*(names[minIndex]) = *(names[i]);
*(names[i]) = stringTemp;
}
}
void displayData(string *names[], int *scores[], int num)
{
cout << "Top scorers: " << endl;
for(int i=0;i<num;i++)
{
cout << names[i] <<": ";
cout << scores[i] << endl;
}
}
and my current output:
How many scores would you like to enter?: 10
Segmentation fault (core dumped)
which happens regardless of what int i put there. I put a cout statement after the
cin << num; to see if the program got that far but it never does.
Any help is greatly appreciated. Sorry if this is the most basic error ever.
int **intPoint;
At this point in your code, intPoint doesn't point to anything since you haven't assigned it a value.
*intPoint = new int[num];
Then you dereference it, but it doesn't point to anything.
Try:
int *intPoint;
intPoint = new int[num];
Now you are setting intPoint's value so that it points to the integers you allocated.
The reason you get a segmentation fault is because you dereference an uninitialized pointer.
int **intPoint; // intPoint is declared a pointer to a 'pointer to an int';
// but currently it points to nothing
*intPoint = new int[num]; // *intPoint "dereferences" intPoint, i.e., assigns w/e it
// pointed to (which is nothing) to a pointer.
Like the others have suggested, you didn't need a double pointer here.
int *intPoint; // intPoint is a pointer to an int
intPoint = new int[num]; // notice how we didn't dereference intPoint.
// all we did was assign to our newly minted memory.
Use std::vector in the place of array of int or string.
say,
std::vector<int> scores;
std::vector<string> names;
This way you can avoid all the hassles. This is simple and elegant.
I tried the code below to return an array with all string ids, but it didn't work.
The output just returns a number. How can I return an array with ids?
#include <iostream>
#include <string>
using namespace std;
string* getArray()
{
int nanim;
cout << "Enter the number of animals: ";
cin >> nanim;
string *id = new string[nanim];
for ( size_t i=0; i < nanim; i++ )
{
cout<< "\nEnter id anim "<< i+1 << ": ";
cin >> id[i];
}
for ( size_t i = 0; i < nanim; i++ )
{
cout << id[i] << endl;
}
return id;
}
int main()
{
int n;
cin>>n;
string* anim[n]=getArray();
cout<<anim;
return 0;
}
You are returning a pointer to the first element in the array.
To access array elements just having called string* arr = getArray(); you can use arr[0], arr[1], arr[2] etc. to access the strings.
Don't forget to delete the memory you allocated in the function though; at the moment you have a big memory leak.
Generally this is not good programming though since the function caller doesn't know how many elements there are in the returned array. It would be better to get the number of animals in the caller and pass that into your function.
Better still, rebuild your code to use std::vector as I see you're already using stl. Then you don't need to worry (explicitly) about memory allocation and deallocation.
You do not need to read the number of elements twice, and the type of the anim should be string*, not string* []. Unfortunately, this wouldn't tell you the number of items in the array, so you need to get it from the getArray, for example, like this:
string* getArray(int& nanim) {
// Remove the declaration of nanim, and keep the rest of the code unchanged
...
}
int main()
{
int n;
string* anim = getArray(n);
for (int i=0; i != n; i++) {
cout << anim[i] << endl;
}
delete[] anim;
return 0;
}
This is not an optimal C++ solution, though: you would be much better off using std::vector instead of an array, because the vector grows dynamically, and its size is returned along with the container itself. There would be no need to delete[] the result either, which would significantly simplify your code:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
vector<string> getVector()
{
int nanim;
cout << "Enter the number of animals: ";
cin >> nanim;
vector<string> res;
for ( size_t i=0; i < nanim; i++ )
{
cout<< "\nEnter id anim "<< i+1 << ": ";
string tmp;
cin >> tmp;
res.push_back(tmp);
}
return res;
}
int main()
{
vector<string> anim = getVector();
for ( size_t i = 0; i < anim.size(); i++ )
{
cout << anim[i] << endl;
}
return 0;
}