Access violation writing location 0x00000000. problems with pointers - c++

I'm having trouble with some code for an assignment. The program is based on an online contest problem archive for college students.
Here is the header file:
#include <iostream>
#include <cmath>
using namespace std;
class Vito
{
public:
Vito(int relative_count); //constructor
~Vito(); //destructor
int min(); //finds minimum "distance" between vito's relatives
private:
int *streets; //pointer to array of street numbers
int sum(int index); //generates sum of distances for each of vito's relatives
void getStreetNums(); //retrieves street numbers from user
int relatives; //used globaly to set number of repititions
};
Vito::Vito(int relative_count = 0)
{
int *streets = new int[relative_count]; //allocates memory for array streets
relatives = relative_count;
getStreetNums();
}
Vito::~Vito()
{ delete [] streets; } //releases memory used by class
void Vito::getStreetNums()
{
cout << "Enter all street numbers, seperated by a space: ";
int street_num;
for (int i = 0; i < relatives; i++)
{
cin >> street_num;
streets[i] = street_num;
}
}
int Vito::min()
{
int MIN = 65546, test_distance; //initialized to maximum possible value for an integer in C++
for (int i = 0; i < relatives; i++)
{
test_distance = sum(i);
if( MIN > test_distance )
{ MIN = test_distance; }
}
return MIN;
}
int Vito::sum(int index)
{
int SUM = 0, street_num;
street_num = *(streets+index); //set value for determining distances between one house and the others
for (int i = 0; i < relatives; i++)
{ SUM += abs( street_num - streets[i] ); }
return SUM;
}
Here is the main:
#include <iostream>
#include "proj_02.h"
using namespace std;
int main()
{
int relatives, tests;
cout << "This program will supply a minimum distance between homes based on a given number of relatives and street numbers their homes are on. All entered values must be integers." << endl << endl;
cout << "Enter how many tests will be run: ";
cin >> tests;
for (int i = 0; i < tests; i++)
{
cout << "Enter how many relatives will be used in test " << i+1 << ": ";
cin >> relatives;
Vito family(relatives);
cout << "For this case, the minimum distance between each relatives house compared to each other is: " << family.min() << endl << endl;
}
}
After execution I get an error message saying "0xC0000005: Access violation writing location 0x00000000." here:
void Vito::getStreetNums()
{
cout << "Enter all street numbers, seperated by a space: ";
int street_num;
for (int i = 0; i < relatives; i++)
{
cin >> street_num;
streets[i] = street_num;
}
}
debugging shows that there is a null memory address set for streets, but I allocated memory for it earlier in the constructor. Can anyone explain what's going on here?

Vito::Vito(int relative_count = 0)
{
int *streets = new int[relative_count]; //allocates memory for array streets
In the constructor, you defined a local variable streets, and allocate memory for it. The local variable streets shadows the class member streets. Change it to:
Vito::Vito(int relative_count = 0)
{
streets = new int[relative_count]; //allocates memory for array streets

Related

C++ Calculate the biggest, smallest and average number in different functions and print it. Program will fail to do the arithetics properly

The program will sometimes work properly if i only put the numbers in ascending order. It will fail tho if i try to randomly put numbers. The average number will fail to print properly like the arithmetics didnt work at all I would appreciate any help.
Full question here : Define a class named Student with three private data for
registration number, name and grades in 8 courses (table). Also write the following member functions: A function for assigning values to private class data
• A function for displaying the data
• A function for the return of the maximum score
• A function for the return of the minimum score
• A function for the return of the average score
#include <iostream>
#include <string>
using namespace std;
struct Student
{
private:
string name;
string lname;
string mtr;
int grades[8];
int sum;
int dbv = 0;
int mo;
int min;
int max;
int i, n, p;
public:
void insert()
{
int i;
cout << "\nName : ";
cin >> name;
cout << "\nLast name: ";
cin >> lname;
cout << "\nID : ";
cin >> mtr;
for (i = 1; i < 9; i++)
{
cout << i << ") Give number : ";
cin >> grades[i];
sum += grades[i];
}
}
int average()
{
mo = sum / 8;
}
int minimum()
{
min = grades[0];
for (i = 1; i < 9; i++)
{
if (min > grades[i])
{
min = grades[i];
}
}
}
int maximum()
{
max = grades[0];
for (i = 1; i < 9; i++)
{
if (max < grades[i])
{
max = grades[i];
}
}
}
int print()
{
cout << "\nPRINT : \n Name : " << name << "\n Last Name: " << lname << " \nID : " << mtr << "\nAverage : " << mo << "\nMax : " << max << "\nMin : " << min;
}
};
int main()
{
Student std1;
std1.insert();
std1.average();
std1.minimum();
std1.maximum();
std1.print();
}
In insert, you didn't give a value to grades[0]. So in minimum and maximum, you're comparing grades with a memory garbage.
And, the length of the array is 8, so the index has to be in the range from 0 to 7.
But you're trying to access the 8th element. It means you will get memory garbage again or other variables.

0xC0000005: Access violation writing location 0xCDCDCDCD Dynamic Allocation Error

Getting 0xC0000005: Access violation writing location 0xCDCDCDCD with the code below.
I know I must have not allocated the pointer properly, but I'm not sure where.
I'm trying to have **scoreSet refer to sets of *scores and *scores is to be entered in manually. The names pointer to array is working fine and seems to be allocated properly. The problem is when I try to mimic the same for scoreSet, with the difference being scoreSet is a pointer to an array of pointers scores. I feel like the way I'm trying to dynamically allocate the arrays that this pointer is pointing to is completely wrong.
Basically trying to get something like this to be possible after user input:
scoreSet0 = {22,33,44}
scoreSet1 = {35, 45, 65, 75}
scoreSet3 = {10}
#include <iostream>
#include <string>
using namespace std;
int inputData(string*& names, double**& scores);
int main() {
string *names = nullptr;
double *scores = nullptr;
double **scoreSet = &scores;
int size = 0;
size = inputData(names, scoreSet);
for (int i = 0; i < size; i++) {
cout << *(names+i) << endl;
}
}
int inputData(string*& names, double**& scoreSet) {
int numStudents = 0;
cout << "How many students do you have in the system? ";
cin >> numStudents;
while (numStudents <= 0) {
cout << "Invalid number of students. Please enter number of students: ";
cin >> numStudents;
}
names = new string[numStudents];
cin.ignore(10000, '\n');
for (int i = 0; i < numStudents; i++) {
int numTests = 0;
cout << "Enter the student's name: ";
getline(cin,names[i]);
cout << "Enter how many tests " << *(names + i) << " took: ";
cin >> numTests;
*(scoreSet + i)= new double[numTests]; //Pretty sure this is wrong.
cin.ignore(10000, '\n');
for (int j = 0; j < numTests; j++) { //This loop is causing the error.
cout << "Enter grade #" << j + 1 << ": ";
cin >> *(scoreSet+i)[j];
}
}
return numStudents;
}
Per PaulMcKenzie suggestion, this is how it would roll. It may be a bit much for you to use templates, but if you can... Otherwise create the name and score containers separately. But then you have duplicate code to maintain.
The idea is to keep all your stuff in some kind of order. Note that now the memory management is taken care of in the container.
I dropped handling std::cin and the scores, but it should be much easier for you to code that stuff back without a lot of fluff in the way. At that, develop without std::cin, it is a waste of time. You should write so you can just edit and run.
Also, get out of the habit of using namespace std; It will pay off in the long run.
#define DEV
template<typename T>
struct container {
size_t size;
T* ar;
container(size_t size) :size(size) {
ar = new T[size];
}
~container() { delete[]ar; }
T& operator [](size_t pos) { return ar[pos]; }
};
using names_c = container<std::string>;
using scores_c = container<double>;
size_t inputData(names_c& names, scores_c& scores);
int main() {
container<std::string> names(2);
container<double> scoreSet(2);
auto size = inputData(names, scoreSet);
for (int i = 0; i < size; i++) {
std::cout << names[i] << endl;
}
}
size_t inputData(names_c& names, scores_c& scores) {
#ifdef DEV
size_t numStudents = 2;
names[0] = "tom";
names[1] = "mary";
#else
//do your std::cin stuff
#endif
return names.size;
}
I wasn't going to go there, but. You can extend the concept so that you have containers in containers. Much easier to know what scores go with what student.
struct student_type {
using scores_c = container<double>;
std::string name;
scores_c scores;
};
using student_c = container<student_type>;
I've taken your code, and modified it to work. I've removed your comments, and placed comments in on the lines that I changed.
#include <iostream>
#include <string>
using namespace std;
int inputData( string *&names, double **&scores );
int main() {
string *names = nullptr;
double **scores = nullptr; // Changed to double ** so it's "2D"
// double **scoreSet = &score; // removed, this was unneeded and probably causing problems
int size = 0;
size = inputData( names, scores );
for ( int i = 0; i < size; i++ ) {
cout << *( names + i ) << endl;
}
}
int inputData( string *&names, double **&scoreSet ) {
int numStudents = 0;
cout << "How many students do you have in the system? ";
cin >> numStudents;
while ( numStudents <= 0 ) {
cout << "Invalid number of students. Please enter number of students: ";
cin >> numStudents;
}
names = new string[numStudents];
scoreSet = new double*[numStudents]; // allocate an array of pointers
// cin.ignore( 10000, '\n' ); // Removed from here, placed inside loop
for ( int i = 0; i < numStudents; i++ ) {
cin.ignore( 10000, '\n' ); // placed here so that it always clears before getting the name
int numTests = 0;
cout << "Enter the student's name: ";
getline( cin, names[i] );
cout << "Enter how many tests " << names[i] << " took: "; // simplified
cin >> numTests;
scoreSet[i] = new double[numTests]; // simpliefied left hand side
//cin.ignore( 10000, '\n' ); // not needed
for ( int j = 0; j < numTests; j++ ) {
cout << "Enter grade #" << j + 1 << ": ";
cin >> scoreSet[i][j]; // simplified
}
}
return numStudents;
}

Using a Variable as an Array Parameter in C++

I am trying to write code that will compare a 10 sequence piece of DNA to that of a relative's 10 sequence DNA. The user inputs their name, how many relatives they want to compare, and their DNA. The computer outputs the percentage of a match. ATTAGACGCA compared to ATAAGACGCA would match 90%. The number of relatives is a constant after the user states how many relatives. I have tried using const, but it doesn't seem to want to use the number.
/**********************************************************************
* Get DNA Sequence
***********************************************************************/
void getMyDNA(char myDNA[])
{
cout << "Enter your DNA sequence: ";
cin >> myDNA;
}
/**********************************************************************
* Get Potential Relatives
***********************************************************************/
int getRelatives()
{
int relatives = 0;
cout << "Enter the number of potential relatives: ";
cin >> relatives;
return relatives;
}
/**********************************************************************
* Get Potential Relatives Names
***********************************************************************/
void getRelativeName(string relativeNames[], int relatives)
{
string name;
for (int i = 0; i < relatives; i++)
{
cout << "Please enter the name of relative #" << i + 1 << ": ";
cin >> name;
relativeNames[i] = name;
}
}
/**********************************************************************
* Get Potential Relatives DNA Sequence
***********************************************************************/
void getRelativeDNA(char relativeDNA[][10], string relativeNames[], int relatives)
{
for (int i = 0; i < relatives; i++)
{
cout << "Please enter the DNA sequence for " << relativeNames[i] << ": ";
cin >> relativeDNA[i];
}
}
/**********************************************************************
* Display Potential Relatives Match
***********************************************************************/
void displayMatch(string relativeNames, char relativeDNA[][10], int relatives, char myDNA[])
{
const int family = relatives;
int count[family] = 0;
for (int r = 0; r < 3; r++) //relative number r
{
for (int d = 0; d < 10; d++) //dna piece number d
{
if (relativeDNA[r][d] == myDNA[d])
count[r]++;
}
}
}
/**********************************************************************
* Main
***********************************************************************/
int main()
{
char myDNA[10];
string relativeNames[50];
char relativeDNA[50][10];
// My DNA
getMyDNA(myDNA);
//# of relatives
int relatives = getRelatives();
cout << endl;
//thier names
getRelativeName(relativeNames,relatives);
cout << endl;
//their dna
getRelativeDNA(relativeDNA,relativeNames,relatives);
cout << endl;
//display
displayMatch(relativeNames,relativeDNA,relatives,myDNA);
return 0;
}
Instead of
int count[relatives] = 0;
which is invalid as standard C++ when relatives can vary at run-time, use
std::vector<int> count( relatives );
Include the <vector> header.
If count is a new array create a new array dynamically as follows...
int *count = new int[relatives];
I noticed you're using the following later...
count++;
Are you trying to increment an integer or move a pointer? This code might help make it clearer...
#include <assert.h>
#include <iostream>
#include <typeinfo>
int main(void) {
const int x = 500;
int* a = new int[x];
size_t i = 0;
for(i = 0; i < x;i++) {
a[i] = i;
}
for(i = 0; i < x;i++) {
//Print numbers without moving pointer
std::cout << a[i] << std::endl;
}
for(i = 0; i < x;i++) {
//Print numbers moving pointer
std::cout << a[0] << std::endl;
a++;
}
a = a - x;
delete[] a;
return 0;
}
Even if the parameter is passed as const it won't work. You can try with an array created dynamically
int *count = new int[relatives];

Dynamic arrays using float

I've got a small task I need to complete and I'm rather confused. This task has 3 parts to it which are:
Write a program that dynamically allocates a float array of a size specified by a user (currently working on - if anyone could check my code for this it would be appreciated.
It should then allow the user to input that number of floats, which should be stored in the array. (I have no clue what this means so if I'd appreciate someone explaining it if they could)
Program should print what was saved into the array, the sum, and the average value in the array, and exit.
As you could tell I'm new to C++ and coding in general so please spell it out for me wherever possible. It is mandatory that I am using pointers so I'm afraid I can't change that.
#include <iostream>
using namespace std;
int main()
{
int length;
cout << “Please enter the length of the array: “;
cin >> length;
float * dArray = new float [length];
for (int i = 0; i < length; i++)
{
cin >> dArray[i] = i;
for (int i = 0; i < length; i++)
{
cout << dArray[i] << “ “;
}
cout << ‘/n’;
int sum = 0;
for (int i=0; i < length; i++)
{
sum +=dArray[i];
avg =sum/length;
cout << “Sum is “ << sum << “/nAverage is “ << average;
delete [] dArray;
}
return 0;
}
Please explain the 2nd part.
Thanks in advance.
Regarding
It should then allow the user to input that number of floats, which should be stored in the array. (I have no clue what this means so if I'd appreciate someone explaining it if they could)
It means that you have to let the user input the values to that array. What you are doing is giving them values yourself.
What you need to do is change
for (int i = 0; i < length; i++)
{
dArray[i] = i;
}
to
for (int i = 0; i < length; i++)
{
cin>>dArray[i];
}
Also Note that length should be an int and not a float.
After completion, this would probably be the code you need ( although I would advice you to do the part of finding the sum and average by yourself and use this code I have posted as reference to check for any mistake, as finding the sum and average for this is really easy )
#include <iostream> // include library
using namespace std;
int main() // main function
{
int length; // changed length to int
float sum = 0 , avg; // variables to store sum and average
cout << "Please enter the length of the array: "; // ask user for array
cin >> length;
float *dArray = new float[length];
cout << "\nEnter " << length << " values to be added to the array\n";
for (int i = 0; i < length; i++)
{
cin >> dArray[i]; //accepting values
sum += dArray[i]; // finding sum
}
avg = sum / length; //the average
cout << "\nThe array now contains\n"; // Displaying the array
for ( int i = 0; i < length; i++) // with the loop
{
cout << dArray[i] << " ";
}
cout << "\nThe sum of all values in the array is " << sum; // the sum
cout << "\n\nThe average value is " << avg; // the average
delete[] dArray;
return 0;
}
EDIT
After getting your comment, I decided to post this new code. ( I am assuming what you meant is that the program should repeat as long as the user wants )
I have done it by using a do while loop.
#include <iostream> // include library
using namespace std;
int main() // main function
{
int length; // changed length to int
char a; // a variable to store the user choice
do
{
float sum = 0 , avg; // variables to store sum and average
cout << "\nPlease enter the length of the array: "; // ask user for array
cin >> length;
float *dArray = new float[length];
cout << "\nEnter " << length << " values to be added to the array\n";
for ( int i = 0; i < length; i++ )
{
cin >> dArray[i]; //accepting values
sum += dArray[i]; // finding sum
}
avg = sum / length; //the average
cout << "\nThe array now contains\n"; // Displaying the array
for ( int i = 0; i < length; i++ ) // with the loop
{
cout << dArray[i] << " ";
}
cout << "\nThe sum of all values in the array is " << sum; // the sum
cout << "\n\nThe average value is " << avg; // the average
cout << "\n\nDo you want to try again ( y/n ) ?\n";
cin >> a;
delete[] dArray;
}while( a =='Y' || a == 'y' ); // The do while loop repeats as long as the character entered is Y or y
return 0;
}
Well, hope this is what you were looking for, if not, please do notify me with a comment... :)
Just so you know, the new code you have posted doesn't even compile. Here are some of the problems.
cin >> dArray[i] = i;
You don't need to use = i here. Just cin >> dArray[i] ; is enough.
The next problem is
cout << ‘/n’;
First of all, its \n and not /n. You also need to enclose it in double quotes and not single quotes. That is cout << "\n";
Next one, you have not defined the variable avg . Also note that you have also used an undefined variable average, which I assume you meant avg.
Now here's one of the main problems , You have not closed the curly brackets you opened. You open the brackets for for loops, but forget to close it. I'm leaving that part to you as you need to learn that part yourself by trying.
Now Here's one problem I don't understand, you have used “ “, which is somehow not the same as " ". I don't know if it's something wrong with my computer, or if it's a totally different symbol. My compiler couldn't recognize it. If its not causing any trouble on your end, then don't mind it.
Well, this sums up the problems I noticed in your code ( the problems that I noticed ).
Your issues are too simple for us to just give you the answers, but I've commented your code with suggestions on how to solve your problem:
#include <iostream>
using namespace std;
int main()
{
float length; //it doesn't make sense for something to be of a float length
//should be size_t instead
cout << "Please enter the length of the array: ";
cin >> length;
float *dArray = new float[length];
for (int i = 0; i < length; i++)
{
dArray[i] = i; //this line is incorrect
//how should we read the data into this array?
//we've used cin before
}
for (int i = 0; i < length; i++)
{
cout << dArray[i] << " ";
}
cout << '\n';
//now we've output the array, just need to output the sum and average value
int sum = 0;
for (int i=0; i < length; i++)
{
sum += //what should go here?
}
int average = //how should we calculate the average?
cout << "Sum is " << sum << "\nAverage is " << average;
delete[] dArray;
return 0;
}

C++, Array - Windows Error Crash but no Compiler Error

Ok so here's my code. I'm getting no errors in the compiler, however when I run this program it lets me input 2 names then crashes with a Window's Error. What in the heck am I doing wrong?!
#include <iostream>
using namespace std;
//declaration of variables
int i; // Loop Counter
int x; // Number of Family Members
int main()
{
string FamilyName[x]; // Array of Names
cout << "Enter Number of Family Members" <<endl;
cin >> x;
for (i = 0 ; i < x ; i++){
cout << "Enter Family Member's Name: " <<endl;
cin >> FamilyName[i];
}
for (i = 0 ; i < x ; i++){
cout << FamilyName[i] <<endl;
}
return 0;
}
You can solve the problem in two ways, allocate the array to a large size(x should be initialized...and it should be a constant value) and then the code becomes:
#include <iostream>
#include <string>
using namespace std;
//declaration of variables
int i; // Loop Counter
const int x = 500; // MAX Number of Family Members
int main()
{
string FamilyName[x]; // Array of Names
int count;
cout << "Enter Number of Family Members" <<endl;
cin >> count;
for (i = 0 ; i < count ; i++){
cout << "Enter Family Member's Name: " <<endl;
cin >> FamilyName[i];
}
for (i = 0 ; i < count ; i++){
cout << FamilyName[i] <<endl;
}
return 0;
}
Or use dynamic memory allocation to read the number of family member first and then do the allocation:
int main()
{
int count;
cout << "Enter Number of Family Members" <<endl;
cin >> count;
auto FamilyName = new string[count];
for (i = 0 ; i < count ; i++){
cout << "Enter Family Member's Name: " <<endl;
cin >> FamilyName[i];
}
for (i = 0 ; i < count ; i++){
cout << FamilyName[i] <<endl;
delete[] FamilyName;
}
Hope this helps
You are not allocating any memory to your string array, on this line string FamilyName[x]; // Array of Names x is not defined. It also may be a good idea to set a max array size or have some way of pushing on to the end of the array.
The size of your array should be constant.
Maybe use a vector of strings since vectors can grow dynamically.
string name;
vector<string> FamilyName;
for(int i = 0; i < x; i++)
{
cin >> name;
FamilyName.push_back(name);
}
Either that or give your array a constant size larger than any family size you might encounter.
string FamilyName[100];
if you wouldn't ever get a family with over 100 members.
You need to either allocate reasonable memory for FamilyName or use STL:
string[] FamilyName;
//after get x
FamilyName = new string[x];
or
vector<string> FamilyName;
cin << temp_string;
FamilyName.push_back(temp_string);