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
Related
I'm on exercise 4.34 of the book C++ Primer, 4th edition, which states "Write a program to read strings into a vector. Now, copy that vector into an array of character pointers. For each element in the vector, allocate a new character array and copy the data from the vector element into that character array. Then insert a pointer to the character array into the array of character pointers." I'm also trying to print the vector and character pointer array, and delete the character pointer array afterwards.
Here's what I've come up with so far:
#include <iostream>
#include <string>
#include <vector>
using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::vector;
int main()
{
cout << "Enter some strings:" << endl;
vector<string> svec;
string input;
while (cin >> input) {
svec.push_back(input);
}
size_t sarr_sz = svec.size();
char **sarr = new char*[sarr_sz];
size_t carr_sz, carr_num;
char *carr = NULL;
for (vector<string>::size_type i = 0; i < svec.size(); ++i) {
carr_num = i;
carr_sz = svec[i].size();
carr = new char[carr_sz + 1];
size_t cval;
for (string::size_type j = 0; j < svec[i].size(); ++j) {
cval = j;
carr[cval] = svec[i][j];
}
cval = svec[i].size();
carr[cval] = '\0';
sarr[carr_num] = carr;
}
cout << "Vector contents:" << endl;
for (vector<string>::size_type i = 0; i < svec.size(); ++i) {
cout << svec[i] << " ";
}
cout << endl;
cout << "Character pointer array contents:" << endl;
for (size_t i = 0; i < sarr_sz; ++i) {
cout << sarr[i] << " ";
}
cout << endl;
for (size_t i = 0; i < sarr_sz; ++i) {
delete [] sarr[i];
}
delete [] sarr;
return 0;
}
When I compile and run this program, it freezes at the point after entering the string input and displays no output. When I exit the program manually using Ctrl-C, it displays either Vector Output: <first string inputted> or just Vector Output:. I've gone over the program multiple times and can't figure out where I've made an error.
Please keep in mind that I'm a beginner, and I'm just following the conventions of the book. As such, my program is probably neither efficient nor follows correct style. Any help would be greatly appreciated. Thank you.
Here is the assignment:
Your goal is to write a program that displays a series of whole numbers from input in reverse order. Your
program will prompt the user for the number of values in this list, which it will use as the size for a dynamic
array declared after this prompt.
The array size is unknown, the value is the pointer, and the sub has to be assigned before the loop.
Here are the steps:
Declare variables, but don't "allocate the memory the memory for the pointer yet". Do this after prompting the user to enter the values.
Prompt user to enter the numbers of values to be listed. (There has to be a message for the user in case they enter a negative number). Then use the keyword new for the pointer.
Prompt the user to enter the values
Display the values in reverse.
Use the keyword delete for the dynamic array.
While I'm trying to run the program, the error was:
error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
for(int sub = 0; sub < size; size--)
--------------------------------------^
error: lvalue required as decrement operand
for (int sub = 0; sub > size; size--)
------------------------------------------------------^
Also, I am not sure what the keyword new does.
#include <iostream>
using namespace std;
int main()
{
int size, array;
cout << "How many values would you like to enter? ";
cin >> array;
int value;
int *array = new int[size];
if (size > 0)
{
for (int sub = 0; sub < size; size++)
{
cout << "Enter value #" << size << ": ";
cin >> value;
}
while (size > 0);
}
else
{
while (size < 0)
{
cout << "Size must be positive." << endl;
cout << "How many values would you like to enter? ";
cin >> size;
}
}
cout << "Here are the values you entered in reverse order: \n";
for (int sub = size - 1; sub >= 0; size--)
{
cout << "Value #" << size << " :" << value << endl;
}
delete[] array;
return 0;
}
PS: I know size is supposed to be unknown, but I've encountered another error saying
storage size of ‘size’ isn’t known
So, I add numbers to avoid that error.
Edit:So I changed the code thanks to #MikeCAT, but this error said terminate called after throwing an instance of 'std::bad_array_new_length what(): std::bad_array_new_length. This was because I enter a negative number for the size, which was supposed to happen for the if statement. Also, I need the size to start at 1 after the user enters how many values they want to enter, but the size always starts at the number that was entered.
As the assignment says, you should
Read a value
Allocate a dynamic array using the value read as its size
Read the numbers for the array
#include <iostream>
int main(void) {
// read a number (size of a dynamic array)
int numElements;
std::cin >> numElements;
// allocate a dynamic array
int *array = new int[numElements];
// read values for the dynamic array
for (int i = 0; i < numElements; i++) {
std::cin >> array[i];
}
// print the values in reversed order
for (int i = numElements - 1; i >= 0; i--) {
std::cout << array[i] << '\n';
}
// de-allocate the array
delete[] array;
// exit normally
return 0;
}
Error handling and non-essensial messages are omitted. Try adding them.
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.
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.
The program runs smoothly and I have no errors or warnings when its compiled its just when it gets the end result I just get a load of random letters and numbers no matter what I put in.
Here is the code:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int hold;
int n;
int * result = new int;
int * price = new int;
std::string items[6];
for (n=0; n<6; n++)
{
cout << "Item#" << n+1 << ": ";
cin >> items[n];
}
cout << "\nYou Entered: ";
for (int n=0; n<6; n++)
cout << items[n] << ", ";
for (n=0; n<6; n++)
{
if (items[n] == "ab"){
price[n] = 2650;
}
else if (items[n] == "ae"){
price[n] = 1925;
}
else if (items[n] == "ie"){
price[n] = 3850;
}
else if (items[n] == "bt"){
price[n] = 3000;
}
else if (items[n] == "pd"){
price[n] = 2850;
}
else if (items[n] == "ga"){
price[n] = 2600;
}
}
for (n=0; n<6; n++)
{
result += price[n];
}
cout << "\nTotal gold for this build: " << result;
cin >> hold;
return 0;
}
int * price = new int;
and
int * result = new int;
allocate a single int respectively. You probably meant new int[6].
But then again, you should be using std::vector instead.
I'm disappointed really that you took no advice from - https://stackoverflow.com/a/12868164/673730 - if you had, you wouldn't have this problem now. This is not a good way to learn.
With this declaration: int * price = new int; you only allocate space for a single int, but you go on to use price as an array of int.
To declare an array, use: int *price = new int[5];
As for result, you declare that as a pointer to int also, but you later use it as an int: result += price[n];. No need to result to be a pointer. Also note that you need to initialize your variables explicitly: set result to zero before you begin using it.
just give some comments:
new operater should be used with delete.
"int *result" you declared is a point to int, so you should dereference this point to get the result you want.
exceptions should be taken into consideration, what if the input letter is not in your given list?
Well, result is an int *. This kind of variable usually stores the address of another integer variable, which you get with new int in this specific case. However, with
result += price[n];
you'll modify that address, which would lead to segmentation faults if you were to actually write/read from *result. This is also the reason why you output is strange:
cout << "\nTotal gold for this build: " << result;
This prints the adress stored in result, not the value. Make result an integer and it should work.
Please note that price should be changed too, see Luchian's answer.
Exercise
Change your code so that there is no use of new.
Your program could still fail. What is the initial value of result?
What happens if the user provides a code which is not in your list?
Change the line:
cout << "\nTotal gold for this build: " << result;
to
cout << "\nTotal gold for this build: " << *result;
Result is a pointer, so you need to dereference it, using the * operator;
Edit: Change the declaration of the price array to
int *price = new int[6];
The previous declaration declared a variable, not an array