Why this program gives a Segmentation Fault while calling a function? - c++

This is a part of my program while I run this program I get a segmentation fault. I've narrowed it down to the line:
checkBase(ptr1, ptr2)
i'm passing both of these as pointers. and they are declare as char* and its a runtime error not compile time.
file contains
< a href = "http://www.google.com"> www.spam.google.com < /a >
in this case ptr1 = www.google.com and ptr2 = spam.google.com
while(inf){
count++;
getline(inf, line);
//cout << "*******" << count << "*******" << endl <<line << endl;
p = new char[line.length()+1];
strcpy(p, line.c_str());
if(strstr(p, "href")){
ptr = strstr(p, "href");
while(ptr[0]!='\0'){
ptr += 1;
if(ptr[0] == 'w' && ptr[1] == 'w' && ptr[2] == 'w'){
cout << ptr << endl;
ptr = strtok(ptr, "\"");
cout << "add1 " << ptr << endl;
add1 = ptr;
ptr1 = ptr;
ptr = strtok(NULL, "> ");
add2 = ptr;
ptr2 = ptr;
cout << "ptr1: " << ptr1 << endl << "ptr2: " <<ptr2 << endl;
if(add1 == add2)
cout << "There is an exact match at line: " << count << endl << line << endl;
else{
cout << "in else" << endl;
checkBase(ptr1, ptr2); //THIS GIVES A SEGMENTATION FAULT
}
}
}
}
}
void checkBase(char *add1, char *add2){
cout << "here" << endl;
char *base1[1000000], *base2[1000000];
int count1 = 0, count2 = 0;
base1[count1] = strtok(add1, ".");
while(base1[count1] != NULL){
count1++;
base1[count1] = strtok(NULL, ".");
cout << base1[count1] << endl;
}
base2[count2] = strtok(add2, ".");
while(base2[count2] != NULL){
count2++;
base2[count2] = strtok(NULL, ".");
}
cout << base2[count2-1] << endl;
if(((strcmp(base1[count1-1],base2[count2-1])) != 0) && (strcmp(base1[count1-2], base2[count2-2]) != 0)){
//if((strcmp(base1[count1-1], base2[count2-1]) != 0)){
cout << "Bases do not match: " << endl
<< base1[count1-2] << "." << base1[count1-1] << " and "
<< base2[count2-2] << "." << base2[count2-1] << endl;
//}
}
else{
cout << "Bases match: " << endl
<< base1[count1-2] << "." << base1[count1-1] << " and "
<< base2[count2-2] << "." << base2[count2-1] << endl;
}
}
I have no idea why this is giving a segmenation fault.

char *base1[1000000], *base2[1000000];
No doubt this is causing stack overflow. The stack is limited in size, and creating arrays more than a few kb in size is a bad idea. Try allocating them on the heap, for example vector<char *> base1(1000000)
You should also calculate the exact size required and allocate that much, or push_back on the vector.

A couple of problems, beyond the stack overflow already mentioned by #Neil Kirkwell
Those shouldn't be while loops solely conditioned on base1[count1] != NULL; you should also make sure count1 is less than the number of elements in the array.
If either count2 or count1 is 0 or 1 you will be trying to reference index of -1 and -2... not so good.
use strrchr to search backwards and make your life easier
It's wasteful to build those arrays entirely, since you only seem to care about the last two tokens, you only need two pointers in each.
i.e.
char *one_a = NULL, *one_b = NULL, *two_a=NULL, *two_b = NULL;
char *temp = strtok(add1, ".");
while (temp) {
one_b = one_a;
one_a = temp
temp = strtok(NULL, ".");
}
char *temp = strtok(add2, ".");
while (temp) {
two_b = two_a;
two_a = temp
temp = strtok(NULL, ".");
}
//now just compare one_a with two_a and one_b with two_b and you're done.

Related

C++ errors with releasing Dynamic memory [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
Error - *** error for object 0x7ffeefbff360: pointer being freed was not allocated.
I understand its better to use vectors, but our prof wants us to use it this way.
My unwrap function is giving me errors where I want to release the memory, also when I want to print the pattern using the for loop in the display function it gives me a garbage value out of memory instead of printing out the pattern itself. I tested using cout in the wrap function and it works there but not in my display function.
bool wrap(Gift& theGift){
if (theGift.m_wrap == nullptr) {
cout << "Wrapping gifts..." << endl;
do {
cout << "Enter the number of wrapping layers for the Gift: ";
cin >> theGift.m_wrapLayers;
}while ((theGift.m_wrapLayers <= 0) && cout << "Layers at minimum must be 1, try again." << endl);
theGift.m_wrap = new Wrapping[theGift.m_wrapLayers];
char buffer[100];
int patternLength;
for (int i = 0; i < theGift.m_wrapLayers; i++) {
cout << "Enter wrapping pattern #" << i + 1 << ": ";
cin >> buffer;
patternLength = (unsigned)strlen(buffer);
theGift.m_wrap[i].m_pattern = new char[patternLength + 1];
theGift.m_wrap[i].m_pattern = buffer;
cout << theGift.m_wrap[i].m_pattern << endl;
}
return true;
}else {
cout << "Gift is already wrapped!" << endl;
return false;
}
}
bool unwrap(Gift& theGift){
if (theGift.m_wrap != nullptr) {
cout << "Gift being unwrapped." << endl;
for (int i = 0; i < theGift.m_wrapLayers; i++) {
delete[] theGift.m_wrap[i].m_pattern;
theGift.m_wrap[i].m_pattern = nullptr;
}
delete[] theGift.m_wrap;
theGift.m_wrap = nullptr;
return true;
}else{
cout << "Gift isn't wrapped! Cannot unwrap." << endl;
return false;
}
}
void display(Gift& theGift){
cout << "Gift Details: " << endl;
cout << " Description: " << theGift.m_description << endl;
cout << " Price: " << theGift.m_price << endl;
cout << " Units: " << theGift.m_units << endl;
cout << "Wrap Layers: " << theGift.m_wrapLayers << endl;
for (int i = 0 ; i < theGift.m_wrapLayers; i++) {
cout << "Wrap #" << i + 1 << " ->" << theGift.m_wrap[i].m_pattern << endl;
}
}
Error - *** error for object 0x7ffeefbff360: pointer being freed was not allocated.
in wrap :
char buffer[100];
...
theGift.m_wrap[i].m_pattern = buffer;
you save in the in-out parameter theGift a pointer to the local array buffer (and you have a memory leak for the lost of the allocation done in theGift.m_wrap[i].m_pattern = new char[patternLength + 1]; just before)
and later in unwrap :
delete[] theGift.m_wrap[i].m_pattern;
you try to delete that invalid pointer.
In fact in wrap rather than :
theGift.m_wrap[i].m_pattern = new char[patternLength + 1];
theGift.m_wrap[i].m_pattern = buffer;
you wanted to do :
theGift.m_wrap[i].m_pattern = new char[patternLength + 1];
strcpy(theGift.m_wrap[i].m_pattern, buffer);
Note you can also use std::string for m_pattern rather than array of char, and a std::vector<Wrapping>for m_wrap rather than an array of Wrapping. That simplify a lot, no new nor delete

How do i read a std::string from memory using RPM

Okay, so recently i've been working witth RPM(ReadProccesMemory). But while doing so i bumped into the issue of not being able to read a string the way i wanted it.
This is what i heard/know:
I know, when reading a std::string, i get the memory adress of the string OBJECT and not the adress that contains the actual text.I am also aware of "Small String Optimization", and what it does in theory.
I'd like to be able to read the contents of varString(DefaultString) without changing the code of my dummy program(if possible).
The dummy program im reading:
int main() {
// Variables & Pointers
int varInt = 123456;
string varString = "DefaultString";
cout << sizeof(varString);
char arrChar[128] = { "Long char array right there ->" };
int* ptr2int = &varInt;
int** ptr2ptr = &ptr2int;
int*** ptr2ptr2 = &ptr2ptr;
// Printing them out
while (true){
cout << "Process ID: " << GetCurrentProcessId() << endl << endl;
cout << "varInt (0x" << &varInt << ") = " << varInt << endl;
cout << "varString (" << reinterpret_cast<const void*>(varString.data()) << ") = " << varString << endl;
cout << "arrChar (0x" << &arrChar << ") = " << arrChar << endl << endl;
cout << "ptr2int (0x" << &ptr2int << ") = " << &varInt << endl;
cout << "ptr2ptr (0x" << &ptr2ptr << ") = " << &ptr2int << endl;
cout << "ptr2ptr2 (0x" << &ptr2ptr2 << ") = " << &ptr2ptr << endl << endl;
break;
}
cin.get();
return 0;
}
What im currently doing(wont work as intended):
void reading_string(HANDLE handle_procces) {
uintptr_t memoryAdress_2 = 0x0;
cout << "Please write down the memory adress of \"varString\" > " << flush;
cin >> hex >> memoryAdress_2;
string read_string_object;
ReadProcessMemory(handle_procces, (LPCVOID)memoryAdress_2, &read_string_object, sizeof(string), NULL);
cout << "The value of this memory adress is: " << read_string_object << endl;
}
std::string is a container, offset 0x14 is the size of the char array which it manages. If the string is less than 15 characters, the second variable (offset 0x4 or 0x8 depending on x86/x64) is the char array itself. If it's more than 15 characters, this variable turns into a pointer to the char array which is allocated dynamically
We can use this information to read the string externally, it's a hack but it works
Here some sample code which shows you how it's done:
#include <windows.h>
#include <iostream>
using namespace std;
void ReadExternalString(HANDLE hProc, uintptr_t addr, char* dstArray)
{
//Get the size of the array, offset 0x14 is the size of the array
//it's 0x14 on x86
uintptr_t sizeoffset = 0x14;
//check if x64
if (sizeof(int*) == 8)
{
//assign correct offset
sizeoffset = 0x18;
}
uintptr_t arraySize;
ReadProcessMemory(hProc, (BYTE*)(addr + sizeoffset), &arraySize, sizeof(arraySize), 0);
if (arraySize > 15)
{
uintptr_t addrOfCharArray;
//dereference the pointer in the second member variable to get the dynamic address of the array
ReadProcessMemory(hProc, (BYTE*)(addr + sizeof(void*)), &addrOfCharArray, sizeof(void*), 0);
char buffer[500];
//Read the array into buffer, +1 to get the null terminator
ReadProcessMemory(hProc, (BYTE*)(addrOfCharArray), &buffer, arraySize + 1, 0);
//copy the buffer into our ouput argument
memcpy(dstArray, &buffer, strlen(buffer) + 1);
}
else
{
ReadProcessMemory(hProc, (BYTE*)(addr + sizeof(void*)), dstArray, arraySize, 0);
}
}
std::string ourStringToRead = "Yolo";
int main()
{
HANDLE hProcess = OpenProcess(PROCESS_VM_READ, FALSE, GetCurrentProcessId());
if (hProcess == NULL)
{
cout << "OpenProcess failed. GetLastError = " << dec << GetLastError() << endl;
system("pause");
return EXIT_FAILURE;
}
char* cString = new char[500];
ZeroMemory(cString, 500);
ReadExternalString(hProcess, (uintptr_t)&ourStringToRead, cString);
cout << "string char array = " << cString << endl;
system("pause");
return 0;
}

Segmentation fault on returning int

Below I have my two functions which are, when when insertItem calls findIndex producing a segmentation fault. For some reason this happens when the value is returned. (I will include the cout statements so that it is easy to see exactly where this error happens). I am trying to locate the index of a value which is not in the list so -1 should be returned but never does. The output is below.
template <class ItemType>
int SortedList<ItemType>::findIndex(ItemType item) {
cout << "Entering findIndex function" << endl;
int first = 0;
int last = length-1;
int middle;
bool found = false;
while(!found) {
middle = (first+last)/2;
cout << "In findIndex, this is middle: " << middle << " and this is the item: " << item << " and this is the length: " << length << endl;
if(info[middle] == item) {
cout << "In findIndex found is now true" << endl;
found = true;
}
else if(item < info[middle])
last = middle-1;
else// if(item > info[middle])
first = middle+1;
if(first > last)//else// if(first > last)
break;
}
cout << "About to exit and return value from findIndex function" << endl;
if(found == true) {
cout << "findIndex Function: the index of the found value was " << middle << endl;
return middle;
}
else {
cout << "findindex Function: -1 was returned" << endl;
return -1;
}
}
template <class ItemType>
void SortedList<ItemType>::insertItem(ItemType item) {
cout << "Inside insertItem function, length: " << length << endl;
if(findIndex(item) != -1)
cout << "**Item already in the list" << endl;
else if(length == Max_Items)
cout << "**There is no room in the list" << endl;
else {
cout << "before the try" << endl;
try{
cout << "This is length at the start of the insertItem function: " << length << endl;
if(length == 0) {//if the list is empty item becomes the first item in the list \
cout << "This is right after length==0 in insertItem function" << endl;
info[0] = item;//was this->inf...
length++;
cout << "This is length right after incrementing it up" << length << endl;
}
else {//its not the first item in the list
for(int i = 0; i <= length; i++) {
cout << "This is the length and i respectively right inside the for in insertItem" << length << " " << i << endl;
if(i == length) {
cout << "this is where i == length" << endl;
info[i] = item;
length++;
break;
}
if(info[i] < item)
continue;
//inserting the item where it needs to go
for(int p = length; p > i; p--) {//was >=
info[p] = info[p-1];
}
//item = info[i];
info[i] = item;
length++;
break;
}
}
}catch(...) {cout << "**insertItem failed" << endl;}
}
cout << "This is length at the end of the insert item function: " << length << endl;
}
output:
...
Inside insertItem function, length: 0
Entering findIndex function
In findIndex, this is middle: 0 and this is the item: Name: Eman ID: 81012 and this is the length: 0
About to exit and return value from findIndex function
findindex Function: -1 was returned
Segmentation fault (core dumped)
~$:
So even the print saying -1 was returned is hit but nothing ever gets back to the original function. I am not sure as to what could cause a seg fault in this area. Could this return do it?
The following loop:
for(int p = length; p > i; p--) {
info[p] = info[p-1];
probably writes to 1 index past the length of the array, because valid array indexes probably range from 0 to length - 1.
A write to an illegal memory location can corrupt the stack, and this is likely to manifest as a crash when returning from a function.
Still, you really need to start using a debugger.

Remove substring that contains certain pattern and ends with specific char

For example I have a string like following:
"VISITOR_INFO1_LIVE=USv90B-7CzI; LOGIN_INFO=e486e37a395be3f0e3b3237d090a6829c1oAAAB7IjQiOiAiREVMRUdBVEVEIiwgIjciOiAwLCAiMSI6IDEsICIzIjogMjAxMTk0MTMwNiwgIjgiOiA2MDgwMTg0NTEzNjQsICIxMCI6IDIzOTYyMTEyODczNH0=; PREF=f5=30;HSID=AHuJQBOVR0lQoRt_3; APISID=QaParXGsQcEPCzKg/A1smCfYrfMjxvfEPT; YSC=Vm3Amq5loFM";
I want to remove all the patterns that contains *SID (HSID,APISID here) upto ';'. I also want to remove substring "LOGIN_INFO= ....;"
So, output string should be "VISITOR_INFO1_LIVE=L80EDuHCEF8; PREF=f5=30";
Following is the solution I have come up with but I think performance can be improved:
const char *str ="VISITOR_INFO1_LIVE=USv90B-7CzI; LOGIN_INFO=e486e37a395be3f0e3b3237d090a6829c1oAAAB7IjQiOiAiREVMRUdBVEVEIiwgIjciOiAwLCAiMSI6IDEsICIzIjogMjAxMTk0MTMwNiwgIjgiOiA2MDgwMTg0NTEzNjQsICIxMCI6IDIzOTYyMTEyODczNH0=; PREF=f5=30;HSID=AHuJQBOVR0lQoRt_3; APISID=QaParXGsQcEPCzKg/A1smCfYrfMjxvfEPT; YSC=Vm3Amq5loFM";
char *Cookie = NULL;
cout << "original string is:\n" << str << "\n";
int len = strlen(str)+1;
cout << "length of original string is : " << len << "\n";
Cookie = new char[strlen(str)];
strncpy(Cookie,str,len);
char *p1 = strstr(Cookie,"LOGIN_INFO");
char *p2 = NULL;
if(p1){
p2 = strstr(p1,";")+1;
while(*p2 == ' ') p2++;
}
if(p1 && p2)
memmove(p1,p2,strlen(p2)+1);
char *ID = strstr(Cookie,"SID");
while( ID != NULL){
char *start_pos = NULL, *end_pos = NULL;
while((*ID != ';') && (*ID != Cookie[0]) && (*ID != ' ')){
--ID;
}
if(*ID == Cookie[0]) start_pos = ID;
else start_pos = ID+1;
end_pos = strstr(start_pos,";")+1;
while(*end_pos == ' ')
end_pos++;
memmove(start_pos,end_pos,strlen(end_pos)+1);
// }
/*else
std::cout << "does not find substr " << "\n";*/
// cout << "modified string is :" << Cookie << "\n";
ID = strstr(Cookie,"SID");
}
//cout << "final modified string is : " << Cookie << "\n";
char *Cookie_modified = NULL;
const char *pch = strstr(Cookie,"PREF");
if(pch != NULL){
const char *append = "&f2=8000000";
int len = strlen(Cookie) + strlen(append) + 1;
Cookie_modified = new char[len];
strncpy(Cookie_modified,Cookie,len);
Cookie_modified[len-1] = '\0';
char *p = strstr(Cookie_modified,"PREF");
strncpy(p+(strlen(p)),append,strlen(append));
cout << "modified Cookie is : " << Cookie_modified << "\n";
// cout << "length of modified cookie is : " << strlen(Cookie_modified) << "\n";
}
else{
cout << "do not find reference: " << "\n";
const char *append = ";PERF=f2=8000000";
int len = strlen(Cookie) + strlen(append) + 1;
Cookie_modified = new char[len];
Cookie_modified[len-1] = '\0';
strcat(Cookie_modified,Cookie);
strcat(Cookie_modified,append);
cout << "case 2: modified Cookie is: " << Cookie_modified << "\n";
}
delete[] Cookie;
delete[] Cookie_modified;
return 0;
}
Just use std::regex_replace with the following regex:
([^\s]*SID[^;]*;|[^\s]*LOGIN_INFO[^;]*;)
And replace with empty string.
Live Demo

Invalid null pointer

I am trying to write a program that will parse a string and give each position of word. I cannot figure out why I am getting a
"DEBUG ASSERTION FAILED" Experssion: Invalid null pointer
window when it reaches the last word of the string.
char * pointer_char;
int pos = 0;
std::string str = "This test string will fail at this word..!. ";
int i = 0;
int length = str.length();
char * c = new char [str.size()+1];
std::copy(str.begin(), str.end(), c);
c[str.size()] = '\0';
cout << "Testing string is " << str << endl << endl;
pointer_char = strtok (c," ");
while(pointer_char != NULL)
{
cout << pointer_char << endl;
pointer_char = strtok(NULL, " .!");
string word = pointer_char;
size_t found= str.find(word);
if (found!=string::npos)
cout << "Position of " << word << " found at: " << int(found) << endl;
system("pause");
}
return 0;
The problem is you aren't checking the return value of strtok.
pointer_char = strtok(NULL, " .!");
string word = pointer_char;
You're only testing it at the top of the loop.
pointer_char = strtok(nullptr, " .!");
if (pointer_char == nullptr)
break;