Segmentation Fault in C++ while using string vectors - c++

My code is for an online coding practice site, I have been doing many of the challenges but I cannot seem to get around the segmentation fault error on this one.
The aim of the code is to find the longest length strings in a string vector (up to 10 strings long) and then to return a string vector containing just those longest strings in order.
I believe logically my code works, but I can't test it. I am still new to vectors so can't seem to properly understand other answers on here in relation to my issue.
vector<string> allLongestStrings(vector<string> inputArray) {
vector<string> longestStrings; // vector
int longest_size = longestStrings.size(); // int
int longestArrayCounter = 0; // int. For filling longestStrings whenever
// there is a long string
int longest_string = 0; // int. For recording the size of the longest string
for (int i = 0; i < inputArray.size(); i++) {
// Loop will:
//1. Measure size of string in input array
//2. if longest will change value of longest_string and clear longestStrings
//3. If the same length as longest_string will add it to longestStrings vector
//4. if it is shorter it will be ignored
if (inputArray[i].size() > longest_string) { // input vector
longest_string = inputArray[i].size(); // vector
longestStrings.clear(); //clearing the vector to only store longest string values
longestArrayCounter = 0; //reset counter for longestStrings
longestStrings[longestArrayCounter++] = inputArray[i];//puts new longest string from input into my vector
}
if (inputArray[i].size() == longest_string) {
longestStrings[longestArrayCounter++] =inputArray[i];// my vector and input vector
}
}
return longestStrings;
}

longestStrings.clear();
longestArrayCounter = 0;
longestStrings[longestArrayCounter++] = inputArray[i];
is bad because you are doing assignment to non-existent element.
Instead of the two
longestStrings[longestArrayCounter++] = inputArray[i];
you should do
longestStrings.push_back(inputArray[i]);
Then, std::vector will manage the size for you, so you don't have to manage longestArrayCounter by yourself. Use longestStrings.size() to obtain the size.

Related

strcpy to multi-dimensional array in C++

I've been having issues attempting to copy a word into a multi-dimensional array.
Here is the code I use to create the array:
char *word_buffer;
char *return_result[64];
int buffer_count = 0;
int word_start = 0;
int word_end = 0;
// Some extra, irreverent code.
for (int i = 0; i < length; i += 1) {
if (text[i] == delim) { // Delim is a value such as '\n'
word_end = i;
word_buffer = (char*) malloc(sizeof(char)*64);
strncpy(word_buffer, text + word_start, word_end - word_start); // Copy the word into word_buffer
strcpy(*(return_result + buffer_count), word_buffer);
word_start = i + 1;
}
}
I believe my issue lies with the last line. I attempt to give strcpy a pointer to the address of the 2d array where I want the result of word_buffer to be place. However, this results in a Segmentation Fault.
The goal is to have an array of words returned. I.E.
char *result[10] = { "foo", "bar", "x", "y", "z" };
But to have this done dynamically with code. My code to split the words is working fine. Though, I don't know how to place the value into a 2d array.
Edit: User SHR recommended I try replacing the strcpy line with return_array[buffer_count]=word_buffer;. This does partially work but it crashes after a random amount of values in the array every time. I don't really see how this could be due to high memory usage. Tracking the memory usage of the binary shows nothing out of the ordinary.

How can I find the size of a (* char) array inside of a function?

I understand how to find the size using a string type array:
char * shuffleStrings(string theStrings[])
{
int sz = 0;
while(!theStrings[sz].empty())
{
sz++;
}
sz--;
printf("sz is %d\n", sz);
char * shuffled = new char[sz];
return shuffled;
}
One of my questions in the above example also is, why do I have to decrement the size by 1 to find the true number of elements in the array?
So if the code looked like this:
char * shuffleStrings(char * theStrings[])
{
//how can I find the size??
//I tried this and got a weird continuous block of printing
int i = 0;
while(!theStrings)
{
theStrings++;
i++;
}
printf("sz is %d\n", i);
char * shuffled = new char[i];
return shuffled;
}
You should not decrement the counter to get the real size, in the fist snippet. if you have two element and one empty element, the loop will end with value , which is correct.
In the second snippet, you work on a pointer to a pointr. So the while-condition should be *theStrings (supposing that a NULL pointer ist the marker for the end of your table.
Note that in both cases, if the table would not hold the marker for the end of table, you'd risk to go out of bounds. Why not work with vector<string> ? Then you could get the size without any loop, and would not risk to go out of bounds
What you are seeing here is the "termination" character in the string or '\0'
You can see this better when you use a char* array instead of a string.
Here is an example of a size calculator that I have made.
int getSize(const char* s)
{
unsigned int i = 0;
char x = ' ';
while ((x = s[i++]) != '\0');
return i - 1;
}
As you can see, the char* is terminated with a '\0' character to indicate the end of the string. That is the character that you are counting in your algorithm and that is why you are getting the extra character.
As to your second question, seem to want to create a new array with size of all of the strings.
To do this, you could calculate the length of each string and then add them together to create a new array.

trying to load info from a vector containing classes into a two dimensional string vector

I use an input function I made to take info from a text file and input it into the private fields of a class let's call it student, each time a record is filled with the first row from the text input file I push_back the filled class in the vector students to end up with a vector containing classes which contain the data from the input file.
So now in order to be able to perform manipulations on this data I want to load it into a two dimensional string vector but I'm having a hard time implementing this. Below is how far I have gotten, I feel like at this point I'm running in a circle. Any help is appreciated.
The parameter passed (size) is how many rows there are in the text file which is checked prior to this function running.
void student::loadData(int size)
{
vector <vector<string> > tempVec(size);
string first, middle, last, addressNum, addressStreet,
phone, gender, email, emContactFirst, emContactLast,
ph, emPhone, ID, age;
//FIXME//
for (vector<student>::iterator it = students.begin(); it != students.end(); it++){
for (int i = 0; i < size; size++)
{
tempVec[size].push_back(it->getName());
tempVec[size].push_back(it->getId());
tempVec[size].push_back(it->getAge());
tempVec[size].push_back(it->getPhone());
tempVec[size].push_back(it->getAddress());
tempVec[size].push_back(it->getEmail());
tempVec[size].push_back(it->getEmPhone());
tempVec[size].push_back(it->getEmContact());
tempVec[size].push_back(it->gpa);
tempVec[size].push_back(it->honors);
tempVec[size].push_back(it->major);
it++;
}
}
//trying to output 2-dimensional array for debugging purpouses
//(trying to mimic what the output file would look like)
for (int i = 0; i < size; size++)
{
for (vector<string>::iterator z = tempVec[size].begin(); z != tempVec[size].end(); z++){
//**FIX ME**//;
}
}
}
There are several problems here. Don't increment size in the for loops, you want to increment i.
tempVec[size] is outside the bounds of the vector. You want tempVec[i] instead.
Don't increment it inside the inner for loop.

Why does my array element retrieval function return random value?

I am trying to make an own simple string implementation in C++. My implementation is not \0 delimited, but uses the first element in my character array (the data structure I have chosen to implement the string) as the length of the string.
In essence, I have this as my data structure: typedef char * arrayString; and I have got the following as the implementation of some primal string manipulating routines:
#include "stdafx.h"
#include <iostream>
#include "new_string.h"
// Our string implementation will store the
// length of the string in the first byte of
// the string.
int getLength(const arrayString &s1) {
return s1[0] - '0';
}
void append_str(arrayString &s, char c) {
int length = getLength(s); // get the length of our current string
length++; // account for the new character
arrayString newString = new char[length]; // create a new heap allocated string
newString[0] = length;
// fill the string with the old contents
for (int counter = 1; counter < length; counter++) {
newString[counter] = s[counter];
}
// append the new character
newString[length - 1] = c;
delete[] s; // prevent a memory leak
s = newString;
}
void display(const arrayString &s1) {
int max = getLength(s1);
for (int counter = 1; counter <= max; counter++) {
std::cout << s1[counter];
}
}
void appendTest() {
arrayString a = new char[5];
a[0] = '5'; a[1] = 'f'; a[2] = 'o'; a[3] = 't'; a[4] = 'i';
append_str(a, 's');
display(a);
}
My issue is with the implementation of my function getLength(). I have tried to debug my program inside Visual Studio, and all seems nice and well in the beginning.
The first time getLength() is called, inside the append_str() function, it returns the correct value for the string length (5). When it get's called inside the display(), my own custom string displaying function (to prevent a bug with std::cout), it reads the value (6) correctly, but returns -42? What's going on?
NOTES
Ignore my comments in the code. It's purely educational and it's just me trying to see what level of commenting improves the code and what level reduces its quality.
In get_length(), I had to do first_element - '0' because otherwise, the function would return the ascii value of the arithmetic value inside. For instance, for decimal 6, it returned 54.
This is an educational endeavour, so if you see anything else worth commenting on, or fixing, by all means, let me know.
Since you are getting the length as return s1[0] - '0'; in getLength() you should set then length as newString[0] = length + '0'; instead of newString[0] = length;
As a side why are you storing the size of the string in the array? why not have some sort of integer member that you store the size in. A couple of bytes really isn't going to hurt and now you have a string that can be more than 256 characters long.
You are accessing your array out of bounds at couple of places.
In append_str
for (int counter = 1; counter < length; counter++) {
newString[counter] = s[counter];
}
In the example you presented, the starting string is "5foti" -- without the terminating null character. The maximum valid index is 4. In the above function, length has already been set to 6 and you are accessing s[5].
This can be fixed by changing the conditional in the for statement to counter < length-1;
And in display.
int max = getLength(s1);
for (int counter = 1; counter <= max; counter++) {
std::cout << s1[counter];
}
Here again, you are accessing the array out of bounds by using counter <= max in the loop.
This can be fixed by changing the conditional in the for statement to counter < max;
Here are some improvements, that should also cover your question:
Instead of a typedef, define a class for your string. The class should have an int for the length and a char* for the string data itself.
Use operator overloads in your class "string" so you can append them with + etc.
The - '0' gives me pain. You subtract the ASCII value of 42 from the length, but you do not add it as a character. Also, the length can be 127 at maximum, because char goes from -128 to +127. See point #1.
append_str changes the pointer of your object. That's very bad practice!
Ok, thank you everyone for helping me out.
The problem appeared to be inside the appendTest() function, where I was storing in the first element of the array the character code for the value I wanted to have as a size (i.e storing '5' instead of just 5). It seems that I didn't edit previous code that I had correctly, and that's what caused me the issues.
As an aside to what many of you are asking, why am I not using classes or better design, it's because I want to implement a basic string structure having many constraints, such as no classes, etc. I basically want to use only arrays, and the most I am affording myself is to make them dynamically allocated, i.e resizable.

Print sorted integer array element

I'm trying to find the max and min values of an array. I have 'numArray', which is a string of comma separated numbers (e.g. - 3,5,1,6). I'm using a tokenizer to break them into individual ints and storing them in a separate array. I'm then sorting them and printing the 0th element, however 'nums[0]' prints the whole array in the exact order, as in 3,5,1,6.
I tried commenting the sorting part but I still got the whole array. What am I doing wrong?
I am a beginner in C++.
CString str = numArray;
int i=0;
int nums[50];
int nTokenPos = 0;
CString strToken = str.Tokenize(_T(","), nTokenPos);
while (!strToken.IsEmpty())
{
int x = atoi(strToken);
nums[i]=x;
strToken = str.Tokenize(_T(","), nTokenPos);
i++;
}
std::sort(nums,nums+50);
int min = nums[0];
CString someStr;
someStr.Format(_T("The minimum number is: %d"), min);
minMaxAvg.SetWindowTextA(str);
the error lies in the fact that your argument to minMaxAvg.SetWindowTextA is str when you probably meant to pass someStr, ie. you are passing the original string instead of your newly formatted one.
minMaxAvg.SetWindowTextA(str); /* <- this */
minMaxAvg.SetWindowTextA(someStr); /* <- should be this */