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.
Related
I'm getting an heap corruption error and I can't figure out where it is.
The problem is a coin change problem using dynamic programming. C is the array with the coin values, n is the size of the array, T is the target change, usedCoins is an array where the number of used coins should be mapped (i.e if C[1] = 2 and 3 2-coins are used, usedCoins[2] = 2 with all other indexes to 0.
Here's the code:
bool changeMakingUnlimitedDP(unsigned int C[], unsigned int n, unsigned int T, unsigned int usedCoins[]) {
static auto minCoins = new unsigned int[T+1]{UINT_MAX};
minCoins[0] = 0;
static auto lastCoin = new unsigned int[T+1]{0};
for(int i = 0; i < n; i++)
usedCoins[i] = 0;
for(int i = 0; i < n; i++){
for(int j = 1; j <= T; j++){
if(j >= C[i]){
minCoins[j-C[i]] == 0? minCoins[j] = 1 : minCoins[j] = std::min(1 + minCoins[j - C[i]], minCoins[j-C[i]]);
lastCoin[j] = i;
}
}
}
while(T > 0){
unsigned int last = lastCoin[T];
if(last == UINT_MAX || last < 0) return false;
usedCoins[last]++;
T -= C[last];
}
free(minCoins);
free(lastCoin);
return true;
}
When running on debug mode it goes through.
unfortunately I can't see the forest for the trees and need help. I call a result set via a SELECT statement, which has 70 columns. I initialize my buffer for all 70 columns which are chars and set them with setDataBuffer. Unfortunately I can only retrieve 15-17 records. After that I get an Access Violation error message. If I try next(1000) it does not work at all. I think it has something to do with the pointers but I don't see the error. Does anyone know what I am doing wrong?
#pragma region Arrays
char*** data_array = new char**[70];
for (unsigned int i = 0; i < 70; ++i)
{
data_array[i] = new char*[1000];
for (unsigned int j = 0; j < 1000; ++j)
{
data_array[i][j] = new char[500];
}
}
ub2** size_array = new ub2 * [70];
for (unsigned int i = 0; i < 70; ++i)
{
size_array[i] = new ub2[1000];
}
sb2** ind_array = new sb2 * [70];
for (unsigned int i = 0; i < 70; ++i)
{
ind_array[i] = new sb2[1000];
}
ub2** rc_array = new ub2 * [70];
for (unsigned int i = 0; i < 70; ++i)
{
rc_array[i] = new ub2[1000];
}
#pragma endregion
#pragma region setDataBuffer
for (unsigned int i = 0; i < 70; ++i)
{
resultSet->setDataBuffer(i + 1, data_array[i][0], OCCI_SQLT_STR, 500, size_array[i], ind_array[i], rc_array[i]);
}
#pragma endregion
try
{
ResultSet::Status resultSetStatus = resultSet->next(25);
if (resultSetStatus == ResultSet::Status::DATA_AVAILABLE)
{
unsigned int rowCount = resultSet->getNumArrayRows();
for (unsigned int row = 0; row < rowCount; ++row)
{
for (unsigned int column = 0; column < 70; ++column)
{
auto value = data_array[column][row];
auto vsize = *size_array[column];
std::string cellContent(value, vsize);
}
}
}
}
catch(SQLException& sqlEx)
{
std::string msg = sqlEx.getMessage();
int i = 0;
}
The problem is your allocation of data_array, because you create it as a jagged array, not a contiguous array of memory as needed by setDataBuffer.
If you want do use dynamic allocation using new[] I suggest something like this instead:
using data_type = int8_t[1000][500];
auto data_array = new data_type[70];
Then each element of data_array will be a contiguous area of memory, 1000 * 500 bytes large.
If you want to know the difference between an array of arrays (as in my solution) and your pointer to pointer (jagged array), see e.g. this old answer of mine.
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
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 cant find out whats wrong with this part of my program, i want to find out most occuring number in my structure(array), but it finds only the last number :/
void Daugiausiai(int n)
{
int max = 0;
int sk;
for(int i = 0; i < n; i++){
int kiek = 0;
for(int j=0; j < n; j++){
if(A[i].datamet == A[j].datamet){
kiek++;
if(kiek > max){
max = kiek;
sk = A[i].datamet;
}
}
}
}
}
ps. its only a part of my code
You haven't shown us enough of your code, but it is likely that you are not looking at the real result of your function. The result, sk is local to the function and you don't return it. If you have global variable that is also named sk, it will not be touched by Daugiausiai.
In the same way, you pass the number of elements in your struct array, but work on a global struct. It is good practice to "encapsulate" functions so that they receive the data they work on as arguments and return a result. Your function should therefore pass both array length and array and return the result.
(Such an encapsulation doesn't work in all cases, but here, it has the benefit that you can use the same function for many different arrays of the same structure tape.)
It is also enough to test whether the current number of elements is more than the maximum so far after your counting loop.
Putting all this together:
struct Data {
int datamet;
};
int Daugiausiai(const struct Data A[], int n)
{
int max = 0;
int sk;
for (int i = 0; i < n; i++){
int kiek = 0;
// Count occurrences
for(int j = 0; j < n; j++){
if(A[i].datamet == A[j].datamet) kiek++;
}
// Check for maximum
if (kiek > max) {
max = kiek;
sk = A[i].datamet;
}
}
return sk;
}
And you call it like this:
struct Data A[6] = {{1}, {2}, {1}, {4}, {1}, {2}};
int n = Daugiausiai(A, 6);
printf("%d\n", n); // 1
It would be nice if you had english variable names, so I could read them a bit better ^^. What should your paramter n do? Is that the array-length? And what should yout funtion do? It has no return value or something.
int getMostOccuring(int array[], int length)
{
int current_number;
int current_count = 0;
int most_occuring_number;
int most_occuring_count = 0;
for (int i = 0; i < length; i++)
{
current_number = array[i];
current_count = 0;
for (int j = i; j < length; j++)
{
int test_number = array[j];
if (test_number == current_number)
{
current_count ++;
if (current_count > most_occuring_count)
{
most_occuring_number = current_number;
most_occuring_count = current_count;
}
}
}
}
return most_occuring_number;
}
this should work and return the most occuring number in the given array (it has a bad runtime, but is very simple and good to understand).