Operator >> in dynamic string's arrays don't work [on hold] - c++

Could someone explain me why operator >> works with dynamic array of integers, but not with dynamic array of strings?
int main() {
int size;
cin >> size;
int * pointer;
pointer = new int[size];
string * ptr;
ptr = new string[size];
int a = 0;
while (a < size) {
cin >> pointer[a];
a++;
}
int b = 0;
while (b < size) {
cin >> ptr[b]; //error
b++;
} }

Related

heap corruption detected. c plus plus

I get heap corruption when I run this code.I don't know what the problem is.
ERROR: HEAP CORRUPTION DETECTED: after Normal block.
unsigned int a_or_c_checker(char* a, char* b,int n)
{
unsigned int ans = 1;
for (int j = 0; j < n; j++)
{
if ((a[j]-48) && (b[j]-48)) ans *= 2;
if ((a[j] - 48) && !(b[j] - 48)) return 0;
ans %= 1000000007;
}
return ans;
}
int main()
{
int t;
cin >> t;
unsigned int * res = new unsigned int[t];
for (int i = 0; i < t; i++)
{
int n;
cin >> n;
char * a = new char[n];
char * b = new char[n];
cin >> a;
cin >> b;
res[i] = a_or_c_checker(a, b, n); // heap corruption
delete[] a;
delete[] b;
}
delete[] res;
return 0;
}
I would suggest using std::string, rather than trusting the user's input for the length.
Also remember that the c string "abc" needs char[4] to store it, because it is null terminated and must store the hidden null character.
for (int i = 0; i < t; i++)
{
std::string a;
std::string b;
cin >> a;
cin >> b;
int n = min(a.length(), b.length())
res[i] = a_or_c_checker(a.c_str(), b.c_str(), n);
}

Segmentation fault with allocation of pointer array?

I have spent the past few hours trying to figure out why I am getting a seg-fault. My code runs fine, being that my nameList pointer array is initialized with the names that I enter. However, when I pass nameList to my function to dynamically allocate the right amount of space per name in the createStudentList function. If you have any ideas, please inform me with an explanation, I am not looking only for an answer to fix it. Thank you. (This is an assignment, so some guidelines need to be followed [such as using char arrays instead of strings].)
Here is my code:
#include "main.h"
using namespace std;
const int MAXCHAR = 101;
struct Student
{
char *name;
double gpa;
};
Student ** createStudentList(char ** names, int size);
int main()
{
int size = 0;
char temp[MAXCHAR];
char **nameList = nullptr;
Student **studentList = nullptr;
cout << "Enter amount of names: ";
cin >> size;
cout << endl;
cin.clear();
cin.ignore(10, '\n');
nameList = new char *[size];
for(auto i = 0; i < size; i++)
{
cout << "Enter name: ";
cin.get(temp, MAXCHAR, '\n');
cout << endl;
cin.ignore(10, '\n');
nameList[i] = new char[strlen(temp) + 1];
strcpy(nameList[i], temp);
}
studentList = createStudentList(nameList, size);
return 0;
}
Student ** createStudentList(char ** names, int size)
{
Student **tempStudentList = nullptr;
tempStudentList = new Student *[size];
for(auto idx = 0; idx < size; idx++)
{
tempStudentList[idx]->name = new char[strlen(names[idx]) + 1];
strcpy(tempStudentList[idx]->name, names[idx]);
tempStudentList[idx]->gpa = 0;
}
return tempStudentList;
}
You're not allocating the Student instances in the loop. Try this:
for(auto idx = 0; idx < size; idx++)
{
tempStudentList[idx] = new Student;
tempStudentList[idx]->name = new char[strlen(names[idx]) + 1];
strcpy(tempStudentList[idx]->name, names[idx]);
tempStudentList[idx]->gpa = 0;
}
Also, as pointed out in the comments, this isn't modern C++. You'd be better off using std::string and std::vector. For example, change Student to be:
struct Student
{
std::string name;
double gpa;
};
add use std::vector in createStudentList:
std::vector<Student> createStudentList(const std::vector<string> &names)
{
std::vector<Student> students;
for(auto idx = 0; idx < names.size(); idx++)
{
Student student;
student.name = names[index];
student.gpa = 0
students.push_back(student);
}
return students;
}
This will save you having to allocate raw memory which you would otherwise need to delete.
The reason of segmentation fault:
for(auto idx = 0; idx < size; idx++)
{
// tempStudentList[idx] is `Student *` and you don't allocate memory for it
// this is UB
tempStudentList[idx]->name = new char[strlen(names[idx]) + 1];
strcpy(tempStudentList[idx]->name, names[idx]);
tempStudentList[idx]->gpa = 0;
}
But, tempStudentList don't need to be Student** at all, Student* should be sufficient.
Student * createStudentList(char ** names, int size)
{
Student *tempStudentList = new Student[size];
for(auto idx = 0; idx < size; idx++)
{
tempStudentList[idx].name = new char[strlen(names[idx]) + 1];
strcpy(tempStudentList[idx].name, names[idx]);
tempStudentList[idx].gpa = 0;
}
return tempStudentList;
}
BTW: You need to delete many things, nameList, nameList 's elements, studentList, name of Student, and so on. That's why we should use STLs.

SIGSEGV, Segmentation fault

I'm new to C++ (as will be apparent from my code) and I'm practicing dynamic memory allocation with pointers and arrays, as well as my structures. My code works fine until it accesses the "growArray" function and then it gives me the SIGSEGV error. I can't figure out why though because as far as I can tell I'm passing a pointer to a pointer correctly, and I also allocate space for a new pointer. Is the problem with my structure, or is the problem with passing the pointer, or is the problem with receiving the pointer? I hope the question makes sense.
#include <iostream>
#include <string>
using namespace std;
struct FriendInfo
{
string name;
string address;
string number;
};
FriendInfo *growArray(FriendInfo *p_entry, int *size);
int main()
{
int curNum = 0;
int size = 2;
int userAnswer;
FriendInfo *p_friends = new FriendInfo[size];
cout << "Enter a friend's info?(1 for yes, 0 for no)\n";
cin >> userAnswer;
while (userAnswer != 0)
{
if (curNum == size)
{
p_friends = growArray (p_friends, &size);
}
cout << "What is your friend's name?\n";
cin >> p_friends[curNum].name;
cout << "What is your friend's address?\n";
cin >> p_friends[curNum].address;
cout << "What is your friend's number?\n";
cin >> p_friends[curNum].number;
curNum++;
cout << "Enter another friend? (1 for yes, 0 for no)\n";
cin >> userAnswer;
}
}
FriendInfo *growArray(FriendInfo *p_entry, int *size)
{
*size *= 2;
FriendInfo *p_new_friends = new FriendInfo[*size];
for (int i = 0; i < *size; ++i)
{
p_new_friends[i] = p_entry[i];
}
delete [] p_entry;
return p_new_friends;
}
Your problem is that you're doubling the value of size, even though p_entry is of the initial size. Update the code to this:
FriendInfo *growArray(FriendInfo *p_entry, int *size)
{
int newSize = *size * 2;
FriendInfo *p_new_friends = new FriendInfo[newSize];
for (int i = 0; i < *size; ++i)
{
p_new_friends[i] = p_entry[i];
}
delete [] p_entry;
*size = newSize;
return p_new_friends;
}
In your for loop, you want to stop once you've reached the size of p_entry, not size
FriendInfo *growArray(FriendInfo *p_entry, int *size)
{
int orig_size = *size;
*size *= 2;
FriendInfo *p_new_friends = new FriendInfo[*size];
for (int i = 0; i < orig_size; ++i)
{
p_new_friends[i] = p_entry[i];
}
delete [] p_entry;
return p_new_friends;
}

Creating a 2d Dynamic array with pointers

So for an assignment I have to create a program that will create magic squares when the user inputs an odd number, I have most of the program done but for some reason when I try to populate the squares I get Unhandled exception at 0x00326315 in magic square.exe: 0xC0000005: Access violation reading location 0x00000000
I'm using classes and have the declaration for square as int **square;
Here is the code
#include<iostream>
#include<iomanip>
#include"MagicSquare.h"
using namespace std;
MagicSquare::MagicSquare(): size(0), maxNum(0), row(0), col(0), curNum(0) //Constructor initialize variables
{
}
MagicSquare::~MagicSquare() //Destructor
{
for (int i = 0; i < size; i++)
{
delete[] square[i];
}
delete[] square; //Delete the dynamically allocated memory
}
void MagicSquare::getSize() //Get the size of the magic square
{
cout << "Please enter an odd number for the number of rows/columns: ";
cin >> size;
while (size % 2 == 0) //Check to see if the number entered is odd
{
cout << "The number you entered is not odd, please enter an odd number: ";
cin >> size;
}
int **square = new (nothrow) int*[size];
for (int i = 0; i < size; i++)
{
square[i] = new (nothrow) int[size];
}
maxNum = size * size;
iCount = new (nothrow) int[size];
jCount = new (nothrow) int[size];
}
void MagicSquare::populateSquare()
{
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
square[i][j] = 0; //This is where the error occurs
}
}
curNum = 1;
col = (size - 1) / 2;
square[row][col] = curNum;
curNum += 1;
for (int i = 1; i <= maxNum; i++)
{
row = row - 1;
col = col + 1;
if (col >= size)
col = 0;
if (row < 0)
row = size - 1;
square[row][col] = curNum;
curNum += 1;
}
}
Header file
class MagicSquare
{
private:
int **square;
int size;
int maxNum;
int row;
int col;
int curNum;
int *iCount;
int *jCount;
public:
MagicSquare();
~MagicSquare();
void getSize();
void populateSquare();
void printSquare();
};
source file
#include"MagicSquare.h"
#include<iostream>
using namespace std;
int main()
{
MagicSquare mySquare;
int choice = 1;
while (choice == 1)
{
mySquare.getSize();
mySquare.populateSquare();
mySquare.printSquare();
cout << "\n\nWould you like to create another magic square? 1 for yes, 0 for no: ";
cin >> choice;
while (choice != 1 || choice != 0)
{
cout << "\nInvalid input: \nWould you like to create another magic square? 1 for yes, 0 for no: ";
cin >> choice;
}
}
system("pause");
return 0;
}
You are defining a local variable called square in your getSize() method here:
int **square = new (nothrow) int*[size];.
So you make space for the local variable but never for the class's field.
Change this line to
square = new (nothrow) int*[size];
Also seriously consider checking the results of the calls.
Access violation reading location 0x00000000 is telling you, that you are trying to access a NULL-pointer.
A reason could be, that at least one call of new failed. you should check when allocating the array:
int **square = new (nothrow) int*[size];
if(square == NULL)
//Handle error here
for (int i = 0; i < size; i++)
{
square[i] = new (nothrow) int[size];
if(square == NULL)
//Handle error here
}
But i guess thats not the reason. If I saw it right, you have two functions:
void MagicSquare::getSize()
void MagicSquare::populateSquare()
But the int **square is created in getSize, so if you call populate square, this variable does not exist anymore.
if your class is:
class MagicSquare
{
private:
int **square;
public:
//Methods
}
in getSize you have to store the address in the classes member variable, not a local one you just created:
square = new (nothrow) int*[size]; //without int **

c++ dynamic array initialization crash

I have the following code where i call a function and create a dynamic array of ints and then fill that array with an algorithm
main.cpp
...
int main(void){
srand((long) 1234567);
callFunction1();
return 0;
}
functions.h
...
int *A;
int N;
//prototype
void callFunction2();
void callFunction1(){
int choice;
cin >> choice;
while (choice != 2){
callFunction2();
cin >> choice;
}
}
void callFunction2(){
cout << "Enter array size" << endl;
cin >> N;
A = new int[N];
A[0] = 0;
A[1] = 1;
for (int i=2;i<=N;i++){
A[i] = A[i-1] + A[i-2];
}
}
So the above code will work most of the time but some times it will crash on the line where i initialize the array
A = new int[N];
What could be the cause of this problem?
You are accessing A out of bounds here:
for (int i=2;i<=N;i++){
A[i] = ....
A can only be indexed from 0 up to N-1, i.e. in the range [0, N).
You also have a memory leak in callFunction2.

Resources