Who can explain why access violation reading location erorr is thrown and why in a[] i get "erorr reading characters of string"? I have two strings and must to remove all words from first string that containing other string. What i do wrong?
#include "stdafx.h"
#include<iostream>
#include<cstring>
using namespace std;
char s1[100] = {};
char s2[100] = {};
void Words(char s1[], char s2[]) {
int k = 0;
char*p1 = nullptr;
char*np1 = nullptr;
char*p2 = nullptr;
char*np2 = nullptr;
char *m[20];
char *a[20];
char s3[100] = {};
for (int i = 0; i < 20; i++) {
char n[50] = {};
char l[50] = {};
m[i] = n;
a[i] = l;
}
char delimeter[] = " ,.!?;:";
p2 = strtok_s(s2, delimeter, &np2);
while (p2 != nullptr) {
strcpy(a[k], p2);
k++;
p2 = strtok_s(nullptr, delimeter, &np2);
}
k = 0;
p1 = strtok_s(s1, delimeter, &np1);
while (p1 != nullptr) {
strcpy(m[k], p1);
k++;
p1 = strtok_s(nullptr, delimeter, &np1);
}
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 20; j++) {
if (strcmp(m[i], a[j]) != 0 && m[i] != 0 && a[j] != 0) {
strcat(s3, m[i]);
}
}
}
puts(s3);
for (int i = 0; i < 20; i++) {
delete m[i];
delete a[i];
}
}
Main function:
int main()
{
gets_s(s1);
gets_s(s2);
Words(s1, s2);
return 0;
}
There is at least one problem here:
for (int i = 0; i < 20; i++) {
char n[50] = {};
char l[50] = {};
m[i] = n;
a[i] = l;
}
After that loop all elements of m and a point to variables that have gone out of scope. The variables n and l cease to exist once the scope between the {} of the for loop has been left.
You have many misconceptions about pointers and you should probably read some good book about the C language (the code you wrote is actually more C than C++).
There are certainly more errors.
There is so much evil in here I don't know where to start.
You're calling delete on a statically allocated array
p1, p2, np1, and np2 are all unallocated and you're writing to them
Please use string:
const regex re{ "([^ ,.!?;:]+)" };
vector<string> s1Tokens{ sregex_token_iterator(cbegin(s1), cend(s1), re, 1), sregex_token_iterator() };
vector<string> s2Tokens{ sregex_token_iterator(cbegin(s2), cend(s2), re, 1), sregex_token_iterator() };
sort(begin(s1Tokens), end(s1Tokens));
sort(begin(s2Tokens), end(s2Tokens));
set_difference(cbegin(s1Tokens), cend(s1Tokens), cbegin(s2Tokens), cend(s2Tokens), ostream_iterator<string>(cout, "\n"));
Live Example
This example could easily be fleshed out further if after understanding the above example you find yourself interested in studying further I'd start here: https://stackoverflow.com/a/38595708/2642059
Related
Error occurs when I pass another object to a function -> a.Concat(b);
I have just reverted to C++ from Java for a project. When I pass object by value in this code, then an error occurs. Almost every time it is displaying a different error message, sometimes bad alloc, sometimes displaying half the output. I tried passing by reference and also made a copy constructor but both attempts failed.
#include<iostream>
#include<vector>
#include<string>
using namespace std;
class NFA
{
public:
NFA(string);
NFA(vector<vector<string> >);
NFA Concat(NFA other_nfa);
NFA Union(NFA);
NFA KleeneStar();
void display();
int GetNFASize(){ return ALPHABET_SIZE; }
int getNoOfStates(){ return NO_OF_STATES; }
vector<vector<string> > table;
int ALPHABET_SIZE;
int NO_OF_STATES;
private:
};
NFA::NFA(string input)
{
table.resize(2);
NO_OF_STATES = 2;
for(int i = 0; i < NO_OF_STATES; i++)
{
table[i].resize(ALPHABET_SIZE + 1);
}
table[0][0] = "2";
table[0][1] = input;
table[1][0] = "3";
ALPHABET_SIZE = 3;
}
void NFA::display()
{
for(int i = 0; i < table.size(); i++)
{
for(int j = 0; j < ALPHABET_SIZE; j++)
{
cout << table[i][j] << "\t";
}
cout << endl;
}
}
NFA NFA::Concat(NFA other_nfa)
{
vector<vector<string> > ans_vector;
ans_vector.resize(ALPHABET_SIZE + other_nfa.ALPHABET_SIZE);
for(int i = 0; i < NO_OF_STATES; i++)
{
for(int j = 0; j < ALPHABET_SIZE; j++)
{
ans_vector[i][j] = table[i][j];
}
}
for(int i = other_nfa.NO_OF_STATES - 1; i < other_nfa.NO_OF_STATES; i++)
{
for(int j = 0; j < other_nfa.ALPHABET_SIZE; j++)
{
ans_vector[i][j] = other_nfa.table[i][j];
}
}
ans_vector[NO_OF_STATES - 1][3] = other_nfa.table[0][0];
NFA ansNFA(ans_vector);
}
NFA::NFA(vector<vector<string> >)
{
}
int main()
{
NFA a("a");
a.display();
NFA b("b");
b.display();
NFA ab = a.Concat(b);
system("pause");
return 0;
}
In
NFA::NFA(string input)
{
table.resize(2);
NO_OF_STATES = 2;
for(int i = 0; i < NO_OF_STATES; i++)
{
table[i].resize(ALPHABET_SIZE + 1);
}
table[0][0] = "2";
table[0][1] = input;
table[1][0] = "3";
ALPHABET_SIZE = 3;
}
You variable initializations are out of order. When you use
table[i].resize(ALPHABET_SIZE + 1);
ALPHABET_SIZE contains garbage as you have not set a value yet. Just move ALPHABET_SIZE = 3; before the for loop and you should be okay.
I would also suggest you use a member initialization list for all variables to you can. In this case your constructor would look like
NFA::NFA(string input) : NO_OF_STATES(2), ALPHABET_SIZE(3)
{
table.resize(2);
for(int i = 0; i < NO_OF_STATES; i++)
{
table[i].resize(ALPHABET_SIZE + 1);
}
table[0][0] = "2";
table[0][1] = input;
table[1][0] = "3";
}
You resize a vector<vector<string> but fail to resize any of the contained vectors:
ans_vector.resize(ALPHABET_SIZE + other_nfa.ALPHABET_SIZE);
And then later you index into the nested vectors, which goes out of bounds:
for(int i = 0; i < NO_OF_STATES; i++)
{
for(int j = 0; j < ALPHABET_SIZE; j++)
{
ans_vector[i][j] = table[i][j];
}
}
You'll need to call resize for every vector inside ans_vector, or use push_back, emplace_back etc, which would probably be safer for you.
AlPHABET_SIZE is not defined in:
table[i].resize(ALPHABET_SIZE + 1);
by default, it contains some garbage value. This might be your problem.
NFA::NFA(string input)
{
table.resize(2);
NO_OF_STATES = 2;
for(int i = 0; i < NO_OF_STATES; i++)
{
table[i].resize(ALPHABET_SIZE + 1);
}
table[0][0] = "2";
table[0][1] = input;
table[1][0] = "3";
ALPHABET_SIZE = 3;
}
ALPHABET_SIZE is being used in the ctor of NFA though it was not initialized. it causes weird behaviour.
You are creating three objects a,b,ab. during construction of the object program crashes. it has nothing to do with pass by reference/value or using copy ctor.
From the first look I would say the problem lays in the vector-access of table, which would go out-of-range.
From design-point, several issues:
It seems you _other_nfa can be declared const reference:
NFA NFA::Concat(const NFA& other_nfa)
There is no return. At the end of your Concat method there should be sth. like:
return ansNFA;
It seems within Concat you don't change your member variables like table (which btw. is no good name for a member-variable). If Concat dosn't change the class members, you should declare it const:
NFA NFA::Concat(const NFA& other_nfa) const
I'm finalizing a HW assignment to learn C++ coming from Java and had the code working until they tested it with the entire Gettysburg Address, now I get segment faults. I cannot figure out how to solve this problem, I've tried creating a string using the NEW keyword but still can't get things to sizzle. Any help would be greatly appreciated. Below is the function giving me problems.
void PalindromeFinder::truncateToLargestPalindrome(string& inputString){
//std::string *big = new std::string;
//*big=inputString;
int n = inputString.length();
int longestBegin = 0;
int maxLen = 1;
bool table[1000][1000] = {false};
for (int i = 0; i < n; i++) {
table[i][i] = true;
}
for (int i = 0; i < n-1; i++) {
if (inputString[i] == inputString[i+1]) {
table[i][i+1] = true;
longestBegin = i;
maxLen = 2;
}
}
for (int len = 3; len <= n; len++) {
for (int i = 0; i < n-len+1; i++) {
int j = i+len-1;
if (inputString[i] == inputString[j] && table[i+1][j-1]) {
table[i][j] = true;
longestBegin = i;
maxLen = len;
}
}
}
if(largestPalindromeFound.length()<inputString.substr(longestBegin, maxLen).length()){
this->largestPalindromeFound = inputString.substr(longestBegin, maxLen);}
}
If your input string is bigger than 999 then you'll start accessing memory positions outside of your table matrix that's only 1000x1000.
Accessing memory positions outside of your allocated memory can yield segmentation faults and Gettysburg Address is longer than 1000 characters long.
I need to read a txt file and store it into a matrix (we suppose that it'a a 2x2 matrix). I have a problem with the code below (I semplified it to be more cleat):
#include<stdexcept>
#include<string>
#include<fstream>
using namespace std;
class A{
private:
int **m;
void allocate_mem(int ***ptr){
*ptr = new int *[2];
(*ptr)[0] = new int[2*2];
for(unsigned i = 1; i < 2; i++)
(*ptr)[i] = (*ptr)[0] + i*2;
}
void read_file(string file_input){
ifstream fin(file_input.c_str());
allocate_mem(&m);
char a;
for(unsigned i = 0; i < 2; i++) {
for (unsigned j = 0; j < 2; j++) {
a = fin.get();
if(a=="X"){
//ISO C++ forbids comparison between pointer and integer [-fpermissive]
m[i][j] = 1;
}else{
m[i][j] = 0;
}
}
}
fin.close();
}
public:
A(){
throw logic_error("Error!");
}
A(string file_name){
read_file(file_name);
}
~A(){
delete[] m[0];
delete[] m;
}
};
input.txt
XX
X
I want to store a 2x2 matrix whose elemets are:
11
01
The solution is simple: Write C++ instead of C
Use standard containers instead of manual memory management.
Also, if you know the size of the data at compile-time, why do you use dynamic memory?
int m[2][2];
void read_file(const std::string& file_input) {
ifstream fin(file_input.c_str());
char a;
if( !fin ) throw;
for (std::size_t i = 0; i < 2; i++) {
for (std::size_t j = 0; j < 2; j++) {
a = fin.get();
if (a == 'X') { // '' is for characters, "" for strings. Thats why the compiler
m[i][j] = 1;// warns you (You are comparing the char[], which is decayed to
} else { // char*, with the integer value of the char variable)
m[i][j] = 0;
}
}
}
//Close not needed (RAII)
}
I'm pretty new to C++ and I have some problems with getting into all that pointer stuff. Basically I am passing a pointer to a Function, creating an Array at that pointer. Back in the main function I can't access this array.
Here's my code:
#include <iostream>
using namespace std;
void createArray(char** dict, int* arraysize)
{
*arraysize = 26*26*26*26;
delete dict;
dict = 0;
//Initialisiere character array of character
//char **wortliste = 0;
dict = new char*[*arraysize];
for(int i = 0; i < *arraysize; i++)
dict[i] = new char[5];
int ctr = 0;
//Erstelle Einträge (sortiert)
for (char i = 'A'; i <= 'Z'; i++)
{
for (char j = 'A'; j <= 'Z'; j++)
{
for (char k = 'A'; k <= 'Z'; k++)
{
for (char l = 'A'; l <= 'Z'; l++)
{
dict[ctr][0] = i;
dict[ctr][1] = j;
dict[ctr][2] = k;
dict[ctr][3] = l;
dict[ctr][4] = '\0';
ctr++;
}
}
}
}
}
int main(void)
{
char** dict = 0;
int arraysize;
createArray(dict, &arraysize);
cout << dict[0] << endl << dict[arraysize-1] << endl;
return 0;
}
I can't figure out my error thank you very much in advance.
In C++ parameters are pass by value (unless explicitly marked as being reference parameters), so when you pass dict, a pointer (to a pointer to char) to createArray, the dict inside your function is a different object, albeit with the same initial value, as the dict in main. If you want to see changes to dict in main you would have to pass it by reference, or pass the address of it into a function taking a char ***.
E.g.
void createArray(char**& dict, int* arraysize)
or
void createArray(char*** pdict, int* arraysize)
{ // use (*pdict) instead of dict ...
and
// ...
createArray(&dict, &arraysize);
A more "C++" way to achieve what you want would be to have:
void createArray( std::vector<std::string>& dict );
and to simply have createArray resize the vector to the required size. Using standard containers like vector and string also frees you of the obligation to explicity deallocate that memory that you allocate which is currently missing from your code.
There are a couple of mistakes.
To delete an array:
char **array = /* new with whatever */;
/* do your work */
for (i = 0; i < array_size; ++i)
delete[] array[i];
delete[] array;
To new an array:
char **array = new char *[array_size];
for (i = 0; i < array_size; ++i)
array[i] = new char[array_size_2];
When deleteing, to make sure you don't iterate over a not-newed array, check it against NULL:
for (i = 0; i < array_size; ++i)
{
if (array[i] != NULL) /* Or simply if (array[i]) */
delete[] array[i];
array[i] = NULL;
}
if (array != NULL)
delete[] array;
array = NULL;
alternatively, since delete makes a check for NULL anyway, you can simplify this to:
if (array != NULL)
for (i = 0; i < array_size; ++i)
delete[] array[i]; /* no need to set to NULL after if going to delete the array */
delete[] array;
array = NULL;
Note: delete deletes a single object while delete[] deletes an array.
I can't imagine what you would do with such data, but you can at least use modern techniques.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
vector<string> create() {
vector<string> result;
for (char i = 'A'; i <= 'Z'; ++i) {
for (char j = 'A'; j <= 'Z'; ++j) {
for (char k = 'A'; k <= 'Z'; ++k) {
for (char l = 'A'; l <= 'Z'; ++l) {
result.push_back(string() + i + j + k + l);
}
}
}
}
return result;
}
int main() {
vector<string> data = create();
cout << data.front() << endl << data.back() << endl;
}
Input :
A[4] = {0,4,-1,1000} - Actual Array
P[4] = {1,0,3,2} - Order to be reshuffled
Output:
A[4] = {4,0,1000,-1}
Condition : Don't use an additional array as memory. Can use an extra variable or two.
Problem : I have the below program in C++, but this fails for certain inputs of array P.
#include<iostream>
using namespace std;
void swap(int *a_r,int *r)
{
int temp = *r;
*r = *a_r;
*a_r = temp;
}
int main()
{
int A[4] = {0,4,-1,1000};
int P[4] = {3,0,1,2};
int value = A[0] , dest = P[0];
for(int i=0; i<4;i++)
{
swap(&A[dest],&value);
dest = P[dest];
}
for(int i=0;i<4;i++)
cout<<A[i]<<" ";
}
Since you've got a spare array called P kicking around, and there isn't anything in the question as quoted that stipulates it must be treated as a constant array, you could do:
for (i = 0; i < 4; i++)
P[i] = A[P[i]];
for (i = 0; i < 4; i++)
A[i] = P[i];
If you're not allowed to modify P, then you have to work a lot harder (and you also have to work a lot harder if the data type of A is not the same as, or compatible with, the type of P).
However, I fear this is a sleight-of-hand trick that doesn't really answer the question; it gets the job done, but doesn't answer the question.
First of all, I really like Jonathan's solution, but I feel like I can add some interesting ideas too.
The main observation is that array P consists of several loops.
Let's consider p = {1, 4, 3, 2, 0, 5}. There're three loops: 0 => 1 => 4 => 0, 2 => 3 => 2 and 5 => 5. And to replace variables alongside one loop we need no additional memory at all. We just go through it like this
do {
a[i] = a[p[i]];
i = p[i];
} while (i != first_i);
(The last element needs to be taken special care of, though.) The full working version:
for (int i = 0; i < n; ++i) {
if (p[i] < 0) {
// been at index 'i' already
continue;
}
// new loop found
int j = i;
int first_value = a[i]; // to be put in last position in the chain
int prev_j; // we always store previous 'j' index
do {
a[j] = a[p[j]];
prev_j = j;
j = p[j]; // move to next 'j'
p[prev_j] = -1; // mark element as processed
} while (i != j);
a[prev_j] = first_value;
}
The only problem with my solution is that it uses p array to mark element as 'processed'. Some interviewers may consider it ok, others - not, depending on the solution they have in mind.
int _tmain(int argc, _TCHAR* argv[])
{
A[4] = {0,4,-1,1000}
P[4] = {1,0,3,2}
int temp = arr2[0];
for(int i=0;i<4;i++)
{
for(temp = P[i];i<3;temp = P[temp])
{
if(temp >= i)
{
int data;
data = A[i];
A[i] = A[temp];
A[temp] = data;
break;
}
}
}
_getch();
return 1;
}
int _tmain(int argc, _TCHAR* argv[])
{
A[4] = {0,4,-1,1000}
P[4] = {1,0,3,2}
int temp = arr2[0];
for(int i=0;i<4;i++)
{
for(temp = P[i];i<3;temp = P[temp])
{
if(temp >= i)
{
int data;
data = A[i];
A[i] = A[temp];
A[temp] = data;
break;
}
}
}
_getch();
return 1;
}
Slightly modified to calculate dest value
int main()
{
int A[4] = {0,4,-1,1000};
int P[4] = {3,0,1,2};
int value = A[0], dest = P[0];
for(int i=0; i<4-1;i++)
{
int count=0;
dest = P[i];
while(dest<i){ //if P[i] points to lower value, it got swapped with some other position.
dest = P[dest];
}
swap(&A[dest],&A[i]);
}
for(int i=0;i<4;i++)
cout<<A[i]<<" ";
cout<<"\n";
}
Could argue that it goes against the spirit of the question - but can use multiple stack instances (from a run-time perspective) of a single local variable (code perspective). Being allowed to mutate P is just as uncertain, so, FWIW - a recursive answer...
template <int N>
void shuffle(int (&a)[N], int p[], int i = -1)
{
if (++i < N)
{
int result = a[p[i]];
shuffle(a, p, i);
a[i] = result;
}
}