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.
Related
I made a simple array of struct I made a function to implement the array from users input
but I am struggling to find the right way to free or delete elements in the array ;
here is my code for a better understanding
#include <iostream>
using namespace std;
typedef struct InfStudent
{
int id;
int age;
int lvel;
}studentInfo;
void addElments(studentInfo *s)
{
int i=0;
for(i=0; i<2; i++) {
s[i].id = i;
s[i].age = i * i + 1;
s[i].lvel = i + i + 2;
}
}
int studCounter = 0 ;
void deltetElement(void *studentInfo1 ) {
for (int i = 0; i < 6; i++) {
cout << "empty " << endl;
free(studentInfo1);
}
}
int main()
{
int n;int i;
studentInfo st[2];
addElments(st);
for(i=0; i<2; i++) {
cout<<"enter the Id number of the student "<< endl;
cin >> st[i].id;
cout<<"enter the age of the student "<< endl;
cin >> st[i].age;
cout<<"enter the level of the student "<< endl;
cin >> st[i].lvel;
}
deltetElement(st);
for(i=0; i<2; i++) {
cout << "Id of the student " << i << "\t=" << st[i].id;
cout << "\t Age of the student " << i << "\t=" << st[i].age;
cout << "\tLevel of the student " << i << "\t=" << st[i].lvel;
cout<< endl;
}
return 0;
}
the output
enter the Id number of the student
1234
enter the age of the student
32
enter the level of the student
2
enter the Id number of the student
321
enter the age of the student
2
enter the level of the student
32
empty
it is printing empty, but the code still working like 3 second and then printing empty massage, but I did not understand it does delete or not, or there is a better way to do that;
Since you are using studentInfo st[2]; it's an array of VALUE types, meaning that studentInfo objects are not allocated in heap, and should not be deleted by free() or delete.
free or delete array of strcut c++
You create an array with automatic storage. Automatic objects are destroyed and their storage is released automatically when the variable goes out of scope. You cannot and you must not "free" them in any way other than by letting the execution proceed to the outside of the scope where the automatic object is defined.
Only thing that may be passed to free is a pointer that was returned by malloc (or certain other related C allocation functions) and hasn't previously been freed. Since that doesn't apply to what you pass to free, the behaviour of your program is undefined. That's bad. Don't do that.
P.S. Don't use malloc nor free in C++ if you can avoid it (and it can usually be avoided).
I am struggling to find the right way to free or delete elements in the array ;
The elements of an array are destroyed and their storage released when the array itself is destroyed and its memory is released. There is no way to separate those two.
#include <iostream>
#include <iomanip>
#include <string>
#include <algorithm>
using namespace std;
void getinput (string &first,string &second);
void lengthcheck (string first, string second);
//int anagramcheck (string word);
int* lettercounter (string input);
int main()
{
std::string a;
std::string b;
getinput(a,b);
lengthcheck (a,b);
lettercounter(a);
lettercounter(b);
int* one = lettercounter(a);
int* two = lettercounter(b);
if (one == two)
cout << "You Have Entered An Anagram" << endl;
else
cout << "You Have Not Entered An Anagram" << endl;
}
void getinput (string &first, string &second) {
cout << "Enter First Input: ";
getline(cin, first, '\n');
cout << "Enter Second Input: ";
getline(cin, second, '\n');
cout << "You Entered " << first << " and " << second <<endl;
}
void lengthcheck(string first, string second){
int lengtha = first.length();
int lengthb = second.length();
if ((lengthb > 60) || (lengtha > 60)) {
cout << "Input Is Invalid" << endl;
} else if (lengtha !=lengthb) {
cout << "Input is not an anagram" << endl;
} else {
cout << "Input is Valid" << endl;
}
}
int* lettercounter(string input)
{
static int freq[26] = {0};
int length = input.length();
for (int i=0; i<26; i++) {
freq[i]=0;
}
for (int i=0; i <length; i++) {
if(input[i]>='a' && input[i]<='z')
{
freq[input[i] - 97]++;
}
else if(input[i]>='A' && input[i]<='Z')
{
freq[input[i] - 65]++;
}
}
for(int i=0; i<26; i++) {
/* If current character exists in given string */
if(freq[i] != 0)
{
printf("'%c' = %d\n", (i + 97), freq[i]);
}
return freq;
}
}
I am having trouble returning the array named freq from the user definied function called lettercount. Can someone give me a hint? I need the lettercount to return an array. I need to call the function lettercount twice so i can compare the results of each array to determine if the two inputs are anagrams. I am not sure if the function is returning an actual value to the main.
First of all, freq shouldn't be static. By making it static, you would be accessing the same array everytime. For what you want to do, you don't want to always access the same memory.
In second place, you cannot just return a pointer to memory that has not being allocated dynamically or that isn't static. When you get out of scope (i.e. you return from the function lettercounter back to main), the memory that was occupied by the array will be freed. So, you would be returning a pointer to memory that is no longer reserved, resulting in undefined behavior.
If you really need to work with raw pointers, then each time you enter lettercounter, you would need to allocate memory for the array dynamically like this: int * freq = new int[26];. This will reserve memory for an array of size 26. Then, when you return freq, the memory will still be allocated. However, don't forget that the memory allocated with new doesn't delete itself. You have to clean your mess. In this case, at the end of main you would call delete[] one; and delete[] two;.
int* lettercounter(string input)
{
int * freq = new int[26];
.
.
.
return freq;
}
int main()
{
.
.
int* one = lettercounter(a);
int* two = lettercounter(b);
.
.
delete[] one;
delete[] two;
}
In any case, I'd recommend you to learn to use smart pointers and about standard containers (like a vector). These operations would be much simpler.
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
}
I am busy working on a simple concept to display pointer arrays and iterations of a for loop in C++
My compiler is not giving much away and when I run the program the console is saying the following and returning 3 "The application has requested the Runtime to terminate in an unusual way.
The crash occurs on this line:
cout << i + 1 << " " << *(pArray + i) << endl;
but when I run this program ommiting either i + 1 or *(pArray + i) it runs without errors or crashing.
Is it illegal to try and output as I am trying to do above?
See below for the code:
#include <iostream>
#include <cstdlib>
using namespace std;
int main() {
int * pArray;
int SIZE;
int module;
pArray = new int[SIZE];
cout <<"Enter the number of Assignments ";
cin >> SIZE;
cout <<"input assignment number " ;
for (int i = 0; i < SIZE; i++)
{
cin >> module;
*(pArray + i) = module;
}
// Print array
for (int i = 0; i < SIZE; i++)
{
cout << i + 1 << " " << *(pArray + i) << endl;
}
cout << endl;
delete[] pArray; // Deallocate array via delete[] operator
return 0;
}
I am admittedly a little nervous to ask this question but I just need someone to explain why this is happening as I am battling to find any reference on this type of situation.
Thanks
You use SIZE two lines before you initialize it.
Move
pArray = new int[SIZE];
to after where you obtain the value of SIZE.
(Also: this would be so much easier with std::vector.)
int * pArray;
int SIZE;
int module;
pArray = new int[SIZE];
SIZE is not initialised yet, so, it would be some junk value.
Initialise it before using it.
You could also Check for success/failure of new.
pArray = new(nothrow) int[SIZE];
if(pArray)
//logic
This question already has answers here:
Why no variable size array in stack?
(7 answers)
Closed 8 years ago.
This simple program to read the grade of students. I want to take how many students the user want to enter, but when I'm writing int g[size];it will be compilation error! I wonder how can I write it correct?
#include <iostream>
using namespace std;
int main()
{
int x;
cout << "Enter how many student ..? ";
cin >> x;
const int size = x;
int g[size];
cout << "enter " << size << "your ";
for (int i = 0; i < size; i++){
cin >> g[i];
}
for (int i = 0; i < size; i++){
cout << "student" << i + 1 << "grade is : " << g[i] << endl;
}
system("pause");
return 0 ;
}
The line int g[size]; causes a compile error because size is not known at compile time (but obviously at runtime).
So you need to allocate memory for the array at runtime.
int *g = new int[size]; // instead of int g[size];
This stores a pointer to the first element of the array in g. Now the compiler can no longer track the lifetime of the array and delete it for you when it isn't needed anymore so you need to do this yourself as well.
delete[] g; // this frees the memory again
system("pause");
As a side note: Your program is valid C++14 which is not yet (fully) supported by Microsoft's Visual C++ compiler but other compilers like clang and g++ already support it.