Segmentation fault : Address out of bounds for a pointer in C - c++

I am trying to build and run some complicated code that was written by someone else, I don't know who they are and can't ask them to help. The code reads a bpf (brain potential file) and converts it to a readable ascii format. It has 3 C files, and 2 corresponding header files. I got it to build successfully with minor changes, however now it crashes
with a segmentation fault.
I narrowed the problem down to FindSectionEnd() (in ReadBPFHeader.c) and find that the error occurs when sscanfLine() (in the file sscanfLine.c) is called (code for both is below).
ui1 is defined as unsigned char.
si1 is defined as char.
Just before returning from sscanfLine(), the address pointed to by dp is 0x7e5191, or something similar ending with 191. However, on returning to FindSectionEnd(), dp points to 0x20303035 and it says 'Address 0x20303035 is out of bounds', which then causes a fault at strstr(). The loop in FindSectionEnd() runs without problem for 14 iterations before the fault occurs. I have no idea what is going wrong. I really hope the information I have given here is adequate.
ui1 *FindSectionEnd(ui1 *dp)
{
si1 Line[256], String[256];
int cnt=0;
while (sscanfLine(dp, Line) != EOF){
dp = (ui1 *)strstr(dp, Line);
dp+= strlen(Line);
sscanf(Line,"%s",String);
if(SectionEnd(String))
return(dp);
}
return(NULL);
}
si1 *sscanfLine(ui1 *dp, si1 *s)
{
int i = 0;
*s = NULL;
int cnt = 0;
while (sscanf(dp, "%c", s + i) != EOF){
cnt++;
dp++;
if(*(s + i) == '\n') {
*(s + i + 1) = '\0';
return s;
}
++i;
}
*(s + i) = '\0';
return s;
}

The sscanfLine function doesn't respect the size of the buffer passed in, and if it doesn't find '\n' within the first 256 bytes, happily trashes the stack next to the Line array.
You may be able to work around this by making Line bigger.
If you're going to improve the code, you should pass the buffer size to sscanfLine and make it stop when the count is reached even if a newline wasn't found. While you're at it, instead of returning s, which the caller already has, make sscanfLine return the new value of dp, which will save the caller from needing to use strstr and strlen.

My first guess would be that your string is not null terminated and strstr() segfaults because it reads past the boundaries of the array

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.

C++ time limit exceeded when it doesn't even execute the function

While I was solving a problem in LeetCode, I found something very strange.
I have this line which I assume gives me a time limit exceeded error:
s.erase(i-k, k);
when I comment(//) this line, it doesn't show me time exceed error, but the strange part was, it has never executed even when i didn't comment it.
below is the entire code.
and Here is the problem link.
class Solution {
public:
string removeDuplicates(string s, int k) {
char prev = s[0];
int cnt = 1;
cnt = 1;
for(int i = 1; i < s.size() + 1; i++){
if(s[i] == prev){
cnt++;
} else {
if(cnt == k){
// when input is "abcd" it never comes to this scope
// which is impossible to run erase function.
s.erase(i-k, k);
i = 0;
}
if(i >= s.size()) break;
cnt = 1;
prev = s[i];
}
}
return s;
}
};
When Input is "abcd", it never even go to the if scope where 'erase' function is in.
Although 'erase' function never run, it still affect on the time complexity, and I can't get the reason.
Does anyone can explain this? or is this just problem of LeetCode?
Many online contest servers report Time Exceeding when program encounters critical error (coding bug) and/or crashes.
For example error of reading out of bounds of array. Or dereferencing bad (junk) pointers.
Why Time Exceeded. Because with critical error program can hang up and/or crash. Meaning it also doesn't deliver result in time.
So I think you have to debug your program to find all coding errors, not spending your time optimizing algorithm.
Regarding this line s.erase(i-k, k); - it may crash/hang-up when i < k, then you have negative value, which is not allowed by .erase() method. When you get for example i - k equal to -1 then size_t type (type of first argument of erase) will overflow (wrap around) to value 18446744073709551615 which is defnitely out of bounds, and out of memory border, hence your program may crash and/or hang. Also erase crashes when there is too many chars deleted, i.e. for erase s.erase(a, b) you have to watch that a + b <= s.size(), it is not controlled by erase function.
See documentation of erase method, and don't put negative values as arguments to this method. Check that your algorithm never has negative value i.e. never i < k when calling s.erase(i-k, k);, also never i-k + k > s.size(). To make sure there is no program crash you may do following:
int start = std::min(std::max(0, i-k), int(s.size()));
int num = std::min(k, std::max(0, int(s.size()) - start));
s.erase(start, num);

How to interpret a GDB backtrace in order to determine a segmentation fault?

I am in an entry level programming class. I understand that segmentation faults are due to an error in memory storage somewhere along the way. The program I wrote is supposed to take a file given to us that is in code and contains the instructions to decode it and then print the decoded message.
We have several test cases and my code runs for some of them, but not for the last one. I learned about GDB for debugging for the first time today and used backtrace full to try and source the error, but I'm not totally sure how to interpret what it gave me.
This is the code that I wrote.
**edited code out
When I did a backtrace, this is what it told me.
#2 0x0000000000401523 in main () at main.cpp:42
second = 61 '='
third = 72 'H'
msg = 0x606308
i = 8
chars = ""
first = 90 'Z'
numMess = 8
out = <incomplete type>
name = "input4.txt"
in = <incomplete type>
arr = "IJKLMNOPQRSTUVWXYZABCDEFGH"
I don't know what the backtrace is telling me and I'm unsure of what to do with that information to discover and fix my error.
The hints from the trace are
i = 8
chars = ""
numMess = 8
i equals numMess and chars is empty.
Why does this matter? Looking at where numMess comes from, we see it's used to size the dynamic array pointed at by msg and msg is later indexed by i. when i equals numMess, msg[i] is out of bounds.
So how did this happen?
string chars;
getline(in, chars); // this doesn't make much sense. Reconsider it
for (chars; std::getline(in, chars); i < numMess) {
Here's where things went wrong. A for loop should look something like
for (initializer ; exit condition ; iterator to advance the loop)
but
for (chars; // does nothing. Compiler may be warning you
std::getline(in, chars); // loop exits on failed read
i < numMess) { // does nothing to advance the loop
Nothing in here prevents i from exceeding numMess because i < numMess is not being used as an exit condition. Right, but why doesn't std::getline(in, chars); kick out of the loop when it hits the end of the file? Empty line at the end of the file. chars was successfully set to an empty string.
for ( ; // nothing happening here
i < numMess and std::getline(in, chars) ;
++i) { // and remove the ++i from the end of the loop.
Gets you out of the current predicament and might give you a program that does what you want. Haven't tested it.
But what if there is a mistake in the file and the file exits before reaching numMess? This is the sort of stuff PaulMckenzie is getting at. You're better off not trusting numMess at all and going with something more like
int numMess = 0;
in >> numMess; // not that we care
vector<Messages> msg;
//read file
int i = 0;
string chars;
while (std::getline(in, chars)) { // get each line. Note this gets the empty line, too
Messages temp; // make a temporary for storage
temp.messageNum = i + 1;
temp.codedMessage = chars;
//decode file
for (char &j : chars) {
if (j - 'A' >= 0 && j - 'A' < 26)
j = arr[j - 'A'];
}
temp.decodedMessage = chars;
msg.push_back(temp);
}

C++ Segmentation Fault in a While Loop

I have a loop like this:
while (k < wordnum) { // wordnum is 9 in my case
/*There is a text file that includes some words
*Starting positions of words are kept in wordIndexes
*Don't worry about not having indexes*/
//std::ifstream s_words
s_words.seekg(*(wordIndexes + k) + 1, s_words.beg);
char *p_Word = new char[16];
s_words.getline(p_Word,15,'\n');
//After getting word, they are copied in a struct
word.id = wordnum - k;
word.word = new char [strlen(p_Word)];
strcpy(word.word,p_Word);
word.wordLength = strlen(p_Word);
delete[] p_Word;
//At last, the word is sent for search
if (verticalSearch(puzzleArray, &word)){
k++;
cout<<"Found vertically"<<endl;
delete[] word.word;
}
else if (horizontalSearch(puzzleArray, &word)){
k++;
cout<<"Found horizontally"<<endl;
delete[] word.word;
}
else if (diagonalSearch(puzzleArray, &word)){
k++;
cout<<"Found Diagon Alley"<<endl;
delete[] word.word;
}
else{
k++;
delete[] word.word;
}
}
I know this is not a well designed code but that's not it. While loop and functions work perfectly until the last loop. When the last loop finishes, instead of getting out of the loop, program gives segmentation error. I'm sure that last word is not causing that because it is found in a right way and returned true. Also I'm sure that none of the words more than 15 characters. At the very last, k++ is working and k becomes 9. Then error comes. I'm using linux so I tried to find where is the problem with gdb and I got this:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7534467 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
I don't know what that means. Do this information help me or should I try something else?
p.s: The program working smoothly in windows.
word.word = new char [strlen(p_Word)];
strcpy(word.word,p_Word);
You didn't allocate enough space for word.word. A string with a string length of 15 characters requires 16 characters to store because C-style strings have a nul terminator to mark their end.
The effect of overwriting the bounds of an allocated memory block are unpredictable and can differ on different platforms.
You are making things extra difficult by not using any of the numerous C++ features that make life simpler and by not having any test coverage. For example, if you had a "string duplicate" function to duplicate the string and had test coverage for that function, you would probably have localized this problem yourself.

Length character count using recursive function

I'm trying to create a recursive function that could count the characters of a string, but I don't know why my code is crashing my system. I don't have any more ideas.
Any suggestions:
long slength (const char ntca[])
{
int length = 0;
if (ntca[length] == '\0'){
return 0;
}
else{
return slength(ntca)+1;
}
}
The current code calls slength for the same buffer recursively. This will continue until the stack overflows.
You need to reduce the buffer by one character as well as adding 1 to the length count for each recursive call
return slength(ntca+1)+1;
// ^^
You do not need to declare the local variable. The function can be written simpler
size_t slength( const char s[] )
{
return ( *s == '\0' ? 0 : 1 + slength( s + 1 ) );
}
It's crashing because you're not shortening the string. The line should read
return slength(ntca+1)+1;
Look at the recursive call. If the length of ntca is not zero, then this function calls itself with exactly the same argument. This causes an endless recursion which crashes the stack.
You should work through your algorithm with pencil and paper before you try it in code.
In general, if you use recursion, you have to make a recursive call on a smaller problem size. In your code, you call the function to the same array (or rather, the same pointer to the first element in the array), rather than the pointer to the next element in the array.
However, it's recommended you don't use recursion in C++. Also, since this is such a common thing, there is a strlen() defined in the <cstring> header. Don't define your own functions if there is already a known one in the C++ standard library.
You have to reduce the answer size in your recursion. In other words, try to reduce the size of your string (ntca) in order to stop infinite recursion. Or try to add a parameter to control the recursion like this:
long slength (const char ntca[], int n) //Look from n to the end of string for '\0'
{
if (ntca[n] == '\0')
return n; //the index of char '\0' indicates the length of string
else
return slength(ntca, n+1); //go, check the next char
}
So you always have to call this function as follows:
x = slength(s, 0)