Access Violation Pointer Error - c++

I am implementing my version of the basic String class, however I am running into an issue that I have never seen before and have no idea how to properly debug. My code is pasted below. All functions have their header counterparts. My test is simply creating one object using the convert constructor.
A4String obj1("this");
My problem is I get an Access violation reading location exception thrown. My research has indicated that I may be trying to access memory outside of Visual Studio's allotment. I'm having trouble finding where this pointer error exists though. I have placed breakpoints through every step of the convert constructor and subsequent function calls within however my program doesn't throw the exception until it returns to main, seemingly after my program has executed completely.
#include "A4String.h"
A4String::A4String() {
data = new char[5];
data[0] = '\0';
capacity = 5;
}
A4String::~A4String() {
if (capacity != 0)
delete[] data;
}
//Copy Constructor
A4String::A4String(const A4String &right) {
cout << "copy" << endl;
data = new char[right.capacity + 1];
strcpy(data, right.data, capacity);
capacity = right.capacity;
}
//Convert Constructor
A4String::A4String(const char *sptr) {
cout << "convert" << endl;
capacity = (strlen(sptr)) + 1;
data = new char[capacity + 1];
strcpy(sptr, data, capacity);
}
//Assignment
A4String& A4String::operator = (const A4String & right) {
//if (capacity != 0) delete[] data;
data = new char[right.capacity + 1];
strcpy(data, right.data, capacity);
capacity = right.capacity;
return *this;
}
//Equivalence
bool A4String::operator == (const A4String &right) const {
return (strcmp(data, right.data)) == 0;
}
int A4String::length() const {
return capacity;
}
void A4String::addChar(char) {
//Not implemented yet
}
string A4String::toString() {
string str = "";
int i = 0;
while (data[i] != '\0') {
str += data[i];
i++;
}
return str;
}
void A4String::strcpy(const char *source, char* destination, int size)
{
for (int i = 0; i < 20; i++)
destination[i] = '\0';
int index = 0;
while (source[index] != '\0')
{
destination[index] = source[index];
index++;
}
destination[index] = '\0';
}
int A4String::strcmp(char *str1, char *str2)
{
if (*str1 < *str2)
return -1;
if (*str1 > *str2)
return 1;
if (*str1 == '\0')
return 0;
return strcmp(str1 + 1, str2 + 1);
return 0;
}
int A4String::strlen( char *s)
{
char *start;
start = s;
while (*s != 0)
{
++s;
}
return s - start;
}

The problem is your A4String::strcpy, the line
for (int i = 0; i < 20; i++)
destination[i] = '\0';
The destination has less than 20 characters, so it crashes.

Use of the hard code number 20 in the A4String::strcpy is not right. I suggest changing it to size.
void A4String::strcpy(const char *source, char* destination, int size)
{
// for (int i = 0; i < 20; i++)
for (int i = 0; i < size; i++)
destination[i] = '\0';
int index = 0;
// Add an additional check here also.
// while (source[index] != '\0' )
while (source[index] != '\0' && index < size)
{
destination[index] = source[index];
index++;
}
destination[index] = '\0';
}
Disclaimer Fixing the above function may not fix your crashing problem even though the use of 20 is most likely crashing your program. In other words, there might be other problems in your code too.

Related

C++: Constructor will take string literals when supposed to take type String (not string) [duplicate]

This question already has answers here:
What is The Rule of Three?
(8 answers)
Rule-of-Three becomes Rule-of-Five with C++11? [closed]
(9 answers)
Is the Rule of 5 (for constructors and destructors) outdated?
(5 answers)
Closed 8 months ago.
So I created my own String class that's just supposed to make dealing with char arrays easier, but I found when passing it to a constructor for another class, Folder, I get a runtime error _CrtIsValidHeapPointer(block), which I understand to be an error with me deallocating dynamic memory.
But what I find super funky, is Microsoft Visual Studio will let me pass a string literal to the Folder constructor in place of a String object. Doing so only gives me the same error as before. As well, I only get the _CrtIsValidHeapPointer(block) error when passing a String to a Folder constructor. Creating a String on its own and accessing any of its variables / functions works perfectly fine.
Edit: All constructors declared have been instantiated in the below .cpp files, there is no hidden constructor that should be taking a const char*
main.cpp:
#include "main.h"
#include <iostream>
int main()
{
char someText[5] = "test";
String text(someText);
Folder folder(text, NULL);
cout << folder.getName().getChars();
}
String.cpp:
#include "String.h"
String::String(char* newChars)
{
chars = newChars;
while (chars[size - 1] != '\0')
size++;
chars = new char[size];
for (int i = 0; i < size; i++)
{
chars[i] = newChars[i];
}
}
String::String(const char* newChars)
{
while (newChars[size - 1] != '\0')
size++;
chars = new char[size];
for (int i = 0; i < size; i++)
{
chars[i] = newChars[i];
}
}
String::String()
{
chars = new char[1];
chars[0] = '\0';
}
String::~String()
{
delete[] chars;
}
void String::append(String newString)
{
int newSize = size + newString.size - 1;
char* newChars = new char[newSize];
for (int i = 0; i < size - 1; i++)
{
newChars[i] = chars[i];
}
for (int i = 0; i < newString.size; i++)
{
newChars[size - 1 + i] = newString.chars[i];
}
delete[] chars;
chars = newChars;
size = newSize;
return;
}
bool String::equals(String string2)
{
if (size != string2.size)
return false;
else
{
for (int i = 0; i < size; i++)
{
if (chars[i] != string2.chars[i])
return false;
}
}
return true;
}
char* String::getChars()
{
return chars;
}
void String::setChars(char* newChars)
{
delete[] chars;
chars = newChars;
return;
}
void String::setChars(const char* newChars)
{
size = 1;
while (newChars[size - 1] != '\0')
size++;
delete[] chars;
chars = new char[size];
for (int i = 0; i < size; i++)
{
chars[i] = newChars[i];
}
return;
}
Folder.cpp:
#include "Folder.h"
Folder::Folder(String newName, Folder* newParent)
{
name = newName;
parent = newParent;
return;
}
Folder::Folder(Folder* newParent)
{
parent = newParent;
return;
}
String Folder::getName()
{
return name;
}
Folder* Folder::getParent()
{
return parent;
}
vector<Folder>* Folder::getChildren()
{
return &children;
}
void Folder::setName(String newName)
{
name = newName;
return;
}
void Folder::setParent(Folder* newParent)
{
parent = newParent;
}

C++ program to count repeated words in a cstring

I've been working on a C++ program, I've made the logic but I'm unable to execute it. The question is:
Task: Write a program, using functions only, with the following features.
Program reads paragraph(s) from the file and stores in a string.
Then program counts the occurrence of each word in the paragraph(s) and stores all words with their number of occurrences.
If that word has appeared more than one time in whole string, it should store the word only once along its total occurrences.
The output described in above (in part 3) must be stored in a new file.
Sample input:
is the is and the is and the and is and only that is
Sample output:
is 5
the 3
and 4
only 1
that 1
I'll cut short to Occurrence program that I've written,
My logic is to store token into character array and then compare that array with main character array and do the increment:
void occurances() {
char* string = getInputFromFile();
char separators[] = ",.\n\t ";
char* token;
char* nextToken;
char* temp[100];
token = strtok_s(string, separators, &nextToken);
cout << temp;
int counter = 0;
int i = 0;
while ((token != NULL)) {
temp[i] = token;
i++;
for (int i = 0; i < strlen(string); i++) {
for (int j = 0; j < 100; j++) {
if ((strcmp(token, *temp)) == 0) {
counter++;
}
}
cout << temp << " : " << counter << endl;
}
if (token != NULL) {
token = strtok_s(NULL, separators, &nextToken);
}
}
}
This code is preposterous I know that, But please anyone be kind enough to give me a clue, actually I'm new to C++ . Thank you
If you store token into array this array should grow dynamically because the number of tokens is not known at the beginning. And according to the task description, you cannot use C++ standard containers, so, it is necessary to implement dynamic array manually, for example:
#include <iostream>
std::size_t increase_capacity_value(std::size_t capacity) {
if (capacity == 0) {
return 1;
}
else if (capacity < (SIZE_MAX / 2)) {
return capacity * 2;
}
return SIZE_MAX;
}
bool increase_array_capacity(char**& tokens_array, std::size_t*& tokens_count, std::size_t& capacity) {
const std::size_t new_capacity = increase_capacity_value(capacity);
if (new_capacity <= capacity) {
return false;
}
const std::size_t tokens_array_byte_size = new_capacity * sizeof(char*);
char** const new_tokens_array = static_cast<char**>(std::realloc(tokens_array, tokens_array_byte_size));
if (new_tokens_array == nullptr) {
return false;
}
tokens_array = new_tokens_array;
const std::size_t tokens_count_byte_size = new_capacity * sizeof(std::size_t);
std::size_t* const new_tokens_count = static_cast<std::size_t*>(std::realloc(tokens_count, tokens_count_byte_size));
if (new_tokens_count == nullptr) {
return false;
}
tokens_count = new_tokens_count;
capacity = new_capacity;
return true;
}
bool add_token(char* token, char**& tokens_array, std::size_t*& tokens_count, std::size_t& array_size, std::size_t& array_capacity) {
if (array_size == array_capacity) {
if (!increase_array_capacity(tokens_array, tokens_count, array_capacity)) {
return false;
}
}
tokens_array[array_size] = token;
tokens_count[array_size] = 1;
++array_size;
return true;
}
std::size_t* get_token_count_storage(char* token, char** tokens_array, std::size_t* tokens_count, std::size_t array_size) {
for (std::size_t i = 0; i < array_size; ++i) {
if (std::strcmp(token, tokens_array[i]) == 0) {
return tokens_count + i;
}
}
return nullptr;
}
bool process_token(char* token, char**& tokens_array, std::size_t*& tokens_count, std::size_t& array_size, std::size_t& array_capacity) {
std::size_t* token_count_ptr = get_token_count_storage(token, tokens_array, tokens_count, array_size);
if (token_count_ptr == nullptr) {
if (!add_token(token, tokens_array, tokens_count, array_size, array_capacity)) {
return false;
}
}
else {
++(*token_count_ptr);
}
return true;
}
int main() {
char string[] = "is the is and the is and the and is and only that is";
char separators[] = ",.\n\t ";
std::size_t token_array_capacity = 0;
std::size_t token_array_size = 0;
char** tokens_array = nullptr;
std::size_t* tokens_count = nullptr;
char* current_token = std::strtok(string, separators);
while (current_token != nullptr) {
if (!process_token(current_token, tokens_array, tokens_count, token_array_size, token_array_capacity)) {
break;
}
current_token = std::strtok(nullptr, separators);
}
// print the report only if all tokens were processed
if (current_token == nullptr) {
for (std::size_t i = 0; i < token_array_size; ++i) {
std::cout << tokens_array[i] << " : " << tokens_count[i] << std::endl;
}
}
std::free(tokens_array);
std::free(tokens_count);
}
godbolt.org
okay what if i want to store any token once, in an array and then replace it with new word while deleting duplicates in character array
It is also possible solution. But in general case, it is also necessary to allocate the memory dynamically for the current token. Because the lengths of tokens are also not known at the beginning:
void replace_chars(char* str, const char* chars_to_replace) {
while (str && *str != '\0') {
str = std::strpbrk(str, chars_to_replace);
if (str == nullptr) {
break;
}
const std::size_t number_of_delimiters = std::strspn(str, chars_to_replace);
for (std::size_t i = 0; i < number_of_delimiters; ++i) {
str[i] = '\0';
}
str += number_of_delimiters;
}
}
bool keep_token(char*& token_storage, const char* new_token) {
if (new_token == nullptr) {
return false;
}
const std::size_t current_token_len = token_storage ? std::strlen(token_storage) : 0;
const std::size_t requried_token_len = std::strlen(new_token);
if (token_storage == nullptr || current_token_len < requried_token_len) {
token_storage =
static_cast<char*>(std::realloc(token_storage, (requried_token_len + 1) * sizeof(char)));
if (token_storage == nullptr) {
return false;
}
}
std::strcpy(token_storage, new_token);
return true;
}
std::size_t count_tokens_and_replace(char* str, std::size_t str_len, const char* token) {
std::size_t number_of_tokens = 0;
std::size_t i = 0;
while (i < str_len) {
while (str[i] == '\0') ++i;
if (std::strcmp(str + i, token) == 0) {
replace_chars(str + i, token);
++number_of_tokens;
}
i += std::strlen(str + i);
}
return number_of_tokens;
}
int main() {
char string[] = "is the is and the is and the and is and only that is";
char separators[] = ",.\n\t ";
const std::size_t string_len = std::strlen(string);
replace_chars(string, separators);
std::size_t i = 0;
char* token = nullptr;
while (true) {
while (i < string_len && string[i] == '\0') ++i;
if (i == string_len || !keep_token(token, string + i)) break;
std::cout << token << " : " << count_tokens_and_replace(string + i, string_len - i, token) << std::endl;
}
std::free(token);
}
godbolt.org
But if it is known that the token length cannot be greater than N, it is possible to use the static array of chars to keep the current token. And it will allow to remove dynamic memory allocation from the code.

Terminate called after throwing an instance of std::bad_alloc. Using two classes, one with a pointer to the other

My program keeps getting me bad alloc error when I use a normal function that contains a member function.
The program is about taking some specific inputs from the command line and printing the elements of an array of pointers. This has to be done with array of pointers.
To begin with, I created a class that needs to have 2 strings. One for the name and one for the room. Then I created another class with a size and a pointer to my first class in order to create an array.
My main is at the end, and above main are the 2 normal functions. What is wrong with this code? When I type the commands for the first time of the loop it works until I enter a command that connects to a normal function. Probably something is wrong there but I can't seem to find it.
#include <iostream>
#include <string>
using namespace std;
class Address
{
private:
string name;
string room;
public:
Address(){};
Address(string, string);
string get_name();
string get_room();
void change_room(string);
};
Address::Address (string n, string r)
{
name = n;
room = r;
}
string Address::get_name()
{
return name;
}
string Address::get_room()
{
return room;
}
void Address::change_room(string change)
{
room = change;
}
//end of Address class
class Address_Book
{
private:
int size;
Address* addresses;
public:
Address_Book();
~Address_Book(){ delete[] addresses;}
void add(Address);
void move(string, string);
int get_size();
Address location(int);
int find(string);
void clear();
void remove_address(string);
int exists(string);
void sort();
};
Address_Book::Address_Book()
{
int s = 0;
size = s;
addresses = new Address[s];
}
void Address_Book::add(Address add)
{
Address* temp = new Address [size + 1];
for (int i = 0; i < size; i++)
{
temp[i] = addresses[i];
}
temp[size] = add;
delete[] addresses;
addresses = temp;
size ++;
}
void Address_Book::move(string name, string newroom)
{
for (int i = 0; i < size ; i++)
{
if (addresses[i].get_name() == name )
{
addresses[i].change_room(newroom);
}
}
}
void Address_Book::remove_address(string name)
{
Address* temp = new Address [size - 1];
for (int i = 0; i < size; i++)
{
if (addresses[i].get_name() != name)
{
temp[i] = addresses[i];
}
else if (addresses[i].get_name() == name)
{
for (int j = i + 1; j < size; j++)
{
temp[i] = addresses[j];
i++;
}
break;
}
}
delete[] addresses;
addresses = temp;
size--;
}
int Address_Book::get_size()
{
return size;
}
Address Address_Book::location(int index)
{
return addresses[index];
}
void Address_Book::sort()
{
Address temp;
for (int i = 0; i < size; i++)
{
for(int j = 0; j < size - 1; j++)
{
if (addresses[j].get_room() > addresses[j + 1].get_room())
{
temp = addresses[j];
addresses[j] = addresses[j + 1];
addresses[j + 1] = temp;
}
}
}
for (int i = 0; i < size; i++)
{
if (addresses[i].get_room() == addresses[i + 1].get_room())
{
if (addresses[i].get_name() > addresses[i + 1].get_name())
{
temp = addresses[i];
addresses[i] = addresses[i + 1];
addresses[i + 1] = temp;
}
}
}
}
void Address_Book::clear()
{
Address * temp = new Address[0];
delete[] addresses;
addresses = temp;
size = 0;
}
int Address_Book::find(string name)
{
for (int i = 0; i < size; i++)
{
if (addresses[i].get_name() == name)
{
return i;
}
}
return -1;
}
//end of Address_Book class
void find(string name, Address_Book addbook)
{
int index = addbook.find(name);
cout << index << endl;
if (index > -1)
{
cout << addbook.location(index).get_name() << " is in room " <<
addbook.location(index).get_room() << endl;
}
else
{
throw runtime_error("entry does not exist.");
}
}
void remove_add(string name, Address_Book book)
{
int exist = book.find(name);
if (exist > -1)
{
book.remove_address(name);
}
else
{
throw runtime_error("entry does not existt.");
}
}
int main()
{
Address_Book addbook;
string action, in_name, in_room;
do
{
try
{
cout << "> ";
cin >> action;
if (action == "add")
{
cin >> in_name >> in_room;
Address newadd(in_name, in_room);
addbook.add(newadd);
}
else if (action == "move")
{
cin >> in_name >> in_room;
addbook.move(in_name, in_room);
}
else if (action == "remove")
{
cin >> in_name;
remove_add(in_name, addbook);
}
else if (action == "find")
{
cin >> in_name;
find(in_name, addbook);
}
else if (action == "list")
{
addbook.sort();
for (int i = 0; i < addbook.get_size(); i++)
{
cout << addbook.location(i).get_name() << " is in room
" << addbook.location(i).get_room() << endl;
}
}
else if (action == "clear")
{
addbook.clear();
}
else
{
throw runtime_error("input mismatch.");
}
}
catch (runtime_error& e)
{
cerr << "error: " << e.what() << endl;
}
}while (action != "exit");
return 0;
}
The function remove_add needs to get the address book object by reference or by pointer.
The way it is now, it removes from a copy of the address book.
It should look like this:
void remove_add(string name, Address_Book& book)
{
int exist = book.find(name);
if (exist > -1)
{
book.remove_address(name);
}
else
{
throw runtime_error("entry does not existt.");
}
}
Also, you should probably do something different in case size == 1 in the following function. e.g. set addresses to NULL, zero or nullptr if your compiler supports it.
void Address_Book::remove_address(string name)
{
Address* temp = new Address[size - 1];
for (int i = 0; i < size; i++)
{
if (addresses[i].get_name() != name)
{
temp[i] = addresses[i];
}
else if (addresses[i].get_name() == name)
{
for (int j = i + 1; j < size; j++)
{
temp[i] = addresses[j];
i++;
}
break;
}
}
delete[] addresses;
addresses = temp;
size--;
}
Have fun learning the language and good luck :)
The exact commands that lead to your problem are not specified in your question, so I poked around a little bit until the code crashed with a segmentation fault.
Valgrind and Dr. Memory are awesome tools for finding root causes of such problems. In your case:
$ g++ -g 46865300.cpp
$ valgrind ./a.out
> add foo bar
> list
==102== Invalid read of size 8
==102== at 0x4EF4EF8: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&) (in /usr/lib64/libstdc++.so.6.0.19)
==102== by 0x401354: Address::get_room() (46865300.cpp:33)
==102== by 0x401C05: Address_Book::sort() (46865300.cpp:152)
==102== by 0x4026A3: main (46865300.cpp:262)
==102== Address 0x5a17410 is 8 bytes after a block of size 24 alloc'd
==102== at 0x4C2A8A8: operator new[](unsigned long) (vg_replace_malloc.c:423)
==102== by 0x4014BF: Address_Book::add(Address) (46865300.cpp:74)
==102== by 0x40245C: main (46865300.cpp:243)
It says that the following code performs out-of-bounds access:
150 for (int i = 0; i < size; i++)
151 {
152 if (addresses[i].get_room() == addresses[i + 1].get_room())
153 {
154 if (addresses[i].get_name() > addresses[i + 1].get_name())
I guess the loop condition should use "size - 1" instead of "size".

Pointer and orphan memory management

Firstly here is my code:
header:
#pragma once
#include <iostream>
using namespace std;
class CString
{
private://Main attribute
char* str;
private:// Aux attribute
int len;
public:
//constructor and destructor
CString(char* x);
CString() { len = 0; str = NULL; }
~CString()
{
if (NULL != str)
delete[] str;
str = NULL;
}
//some operator
CString operator+(CString x);
CString operator+(char* x);
void operator=(CString x);
//operator() is to extract a part of other CString object
CString operator()(unsigned pos, unsigned c_len);
//operator[] return position of CString::str[pos]
char& operator[](unsigned pos);
//Ostream output
friend ostream& operator<<(ostream& os, CString x);
};
//to do char+CString
CString operator+(char* a, CString x);
header cpp code:
#include "CString.h"
CString::CString(char * x)
{
len = 0;
while(x[len])
len++;
str = new char[len];
for (int i = 0;i < len;i++)
str[i] = x[i];
if (str[len - 1] != '\0')
{
len++;
char* tmp;
tmp = new char[len];
for (int i = 0;i < len - 1;i++)
tmp[i] = str[i];
delete[]str;
str = tmp;
tmp = NULL;
str[len - 1] = '\0';
}
}
CString CString::operator+(CString x)
{
CString* result;
result = new CString;
result->len = this->len + x.len - 1;
result.str=new char[result.len];
for (int i = 0; i < this->len - 1;i++)
{
result->str[i] = this->str[i];
}
for (int i = 0, j = this->len - 1;i < x.len;i++, j++)
{
result->str[j] = x.str[i];
}
return *result;
}
CString CString::operator+(char * x)
{
return CString(*this+CString(x));
}
void CString::operator=(CString x)
{
str = new char[x.len];
for (int i = 0; i < x.len;i++)
str[i] = x.str[i];
len = x.len;
}
CString CString::operator()(unsigned pos, unsigned c_len)
{
CString* result;
result = new CString;
result->len = c_len;
result.str=new char[c_len];
for (int i = pos;i < pos + c_len;i++)
result->str[i - pos] = str[i];
return *result;
}
char& CString::operator[](unsigned pos)
{
if (pos < len - 1)
{
char* ptr;
ptr = this->str + pos;
return *ptr;
}
else
{
int o_len = len;
len = pos + 2;
char* tmp;
tmp = new char[len];
for (int i = 0;i < o_len;i++)
{
tmp[i] = str[i];
}
tmp[len - 1] = '\0';
delete[]str;
str = tmp;
tmp = NULL;
return *(str + pos);
}
}
ostream & operator<<(ostream & os, CString x)
{
os << x.str;
return os;
}
CString operator+(char * a, CString x)
{
return CString(CString(a) + x);
}
main:
CString a("string 1"), b = "Initialize " + a;
b[15] = '2'; cout << a + " - " + b << endl;
CString c = a + b;
cout << "String extracted from string \"" << c
<< "\" from position 3 with length of 6 is: \""
<< c(3, 6) << "\"" << endl;
Problem:
When I try to compile this program, there is no error, but still operator+(CString), operator(), and destructor seem to malfunction.
When I debug this program, my program triggered a breakpoint some where at line CString a("String 1"), b = "initilize " + a; I have no idea why. I am do not know if there is any problem for the rest of the program because I always get stuck at that line. SO if somebody can find out any other problem, please tell me, that will save me another day.
Btw, I just wonder at operator+(CString) and operator(), I have create a pointer then I use new and then I return that pointer, so that I have no change to delete that pointer, will it leave me an orphan memory? Since I have read another question about return a class object, I found out that if I use CString result and then return result, result would be destroyed before return. SO is there any better way to do that?
Summary:
1.My program triggered a breakpoint some where in the second line of main().
2.How to properly return a class object?
P.S: I am really bad at communicating and just have 1 year period of C/C++ learning. So if I have type some thing could give you a cancer, please forgive me.
Sincerely thank you.

Undetermined SIGABRT

I'm at a loss here. I'm new to C/C++, moving from Java, so I'm not too knowledgable on the ins and outs of memory in C, which I think is the issue here.
The following is a class for a custom string, and a set of methods to determine anagrams of said string.
//Constructor
MyString::MyString(const char* input) {
m_c = new char[strlen(input + 1)];
strcpy(m_c, input);
}
bool MyString::IsAnagram(char* in) {
int* a = BuildFreqTable(m_c);
int* b = BuildFreqTable(in);
if (strlen(m_c) != strlen(in))
return false;
for (int i = 0; i<256; i++)
{
if (a[i] != b[i])
return false;
}
return true;
int* MyString::BuildFreqTable(const char* s) {
int* table = new int[256];
for (int i = 0; i < 256; i++)
table[i] = 0;
while (*s)
{
table[(unsigned char)*s]++;
s++;
}
return table;
}
And in main I call the following:
int strtptr = 0;
getline(cin, cmd);
MyString tmp = cmd.c_str();
char* buf = new char[tmp.Length()];
buf[0] = '\0';
do
{
int endptr = tmp.IndexOf(",", strtptr);
if (endptr == -1) {
endptr = tmp.Length();
char* temp = (tmp.Substring(strtptr, endptr - strtptr).GetString());
if (data.IsAnagram(temp))
strcat(buf, temp);
break;
}
else {
char* temp = (tmp.Substring(strtptr, endptr - strtptr).GetString());
if (data.IsAnagram(temp)) {
strcat(buf, temp);
strcat(buf, ",");
}
strtptr = endptr;
strtptr++;
}
} while (true);
cout << buf;
}
This works for singular input strings, but when some number of strings (unsure if number of characters or string delimiters), a SIGABRT comes up. The code for that is:
0x00007ffff7531cc9 in __GI_raise (sig=sig#entry=6)
at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
I'm really at a loss here.