segmentation faults with string.h into queue - c++

Sorry noob question couldn't figure out which functions to use here.
http://www.cplusplus.com/reference/string/string/
Was gonna convert to c-string and write a whole mess of code but I bet there's a good way to do this.
Just trying to append A, B, and C to the end of a string and add it to queue, keep getting segmentation fault tho that terminates in a ??() function after string::assign() (according to debugger)
string a, b, c;
a = s.append("A");
b = s.append("B");
c = s.append("C");
q.add(a);
q.add(b);
q.add(c);
this too ends with segmentation fault.
q.add(s + "A");
q.add(s + "B");
q.add(s + "C");
Also problem with this is it uses the old, so I'll get:
teststringA
teststringAB
teststringABC
instead of expected
teststringA
teststringB
teststringC

What is a segmentation fault?
When your program runs, it has access to certain portions of memory. First, you have local variables in each of your functions; these are stored in the stack. Second, you may have some memory, allocated during runtime (using either malloc, in C, or new, in C++), stored on the heap (you may also hear it called the "free store"). Your program is only allowed to touch memory that belongs to it -- the memory previously mentioned. Any access outside that area will cause a segmentation fault. Segmentation faults are commonly referred to as segfaults.
your second problem is
q.add(s + "A"); // appends A to s hence teststringA
q.add(s + "B"); // teststringA + B hence teststringAB
q.add(s + "C"); //teststringAB + C hence teststringABC
refer document at http://www.cplusplus.com/reference/string/string/append/
Append to string
The current string content is extended by adding an additional appending string at its end.
The arguments passed to the function determine this appending string:
string& append ( const string& str );
Appends a copy of str.
example
// appending to string
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string str;
string str2="Writing ";
string str3="print 10 and then 5 more";
// used in the same order as described above:
str.append(str2); // "Writing "
str.append(str3,6,3); // "10 "
str.append("dots are cool",5); // "dots "
str.append("here: "); // "here: "
str.append(10,'.'); // ".........."
str.append(str3.begin()+8,str3.end()); // " and then 5 more"
str.append<int>(5,0x2E); // "....."
cout << str << endl;
return 0;
}
Output:
Writing 10 dots here: .......... and then 5 more.....

Related

Crypto++ HexEncoder not working consistently

Here's my code
#include <cryptopp/hex.h>
#include <string>
#include <iostream>
void hexlify(CryptoPP::byte* bytes, std::string &hex_string, size_t size)
{
CryptoPP::StringSource ss(bytes, size, true, new CryptoPP::HexEncoder(new CryptoPP::StringSink(hex_string)));
}
void unhexlify(std::string hex_string, CryptoPP::byte* &bytes)
{
std::string decoded;
CryptoPP::StringSource ss(hex_string, true, new CryptoPP::HexDecoder(new CryptoPP::StringSink(decoded)));
std::cout << decoded + "\n"; // For testing
bytes = (CryptoPP::byte*)decoded.data();
}
int main()
{
std::string seed = "BF0F3123B21A60E5AB7615AD06EA16A2BD44D84CED4DCC10AA0413127F87DC60";
std::cout << "\n" + seed + "\n";
CryptoPP::byte* b;
unhexlify(seed, b);
std::string s;
hexlify(b, s, 32);
std::cout << s;
std::cout << "\n\n";
}
It should take the 32-byte, 64-character hex string seed, print it, convert it into bytes, then convert it back into a hex string (s) and print it. I also have it print the decoded string in the unhexlify function.
My expectation is for the output to look like this:
BF0F3123B21A60E5AB7615AD06EA16A2BD44D84CED4DCC10AA0413127F87DC60
?1#?`?v????D?L?M????`
BF0F3123B21A60E5AB7615AD06EA16A2BD44D84CED4DCC10AA0413127F87DC60
The first line (seed) and the third line (s, the seed converted into bytes and back) should be the same. And very rarely, that's exactly what happens. However, most of the time the first and third lines are completely different.
What's weird is that I made zero changes to the code, and I didn't even recompile it. But every time I run the executable, it says something different. What's even weirder is that the third line is different every time I run it. Again, it happens even though I'm running the same executable without changing the code or recompiling. Here are the outputs from 5 runs:
BF0F3123B21A60E5AB7615AD06EA16A2BD44D84CED4DCC10AA0413127F87DC60
?1#?`?v????D?L?M????`
205BC0AE8B7F0000AB7615AD06EA16A2889A960301000000189C960301000000
BF0F3123B21A60E5AB7615AD06EA16A2BD44D84CED4DCC10AA0413127F87DC60
?1#?`?v????D?L?M????`
205B40C2B87F0000AB7615AD06EA16A288FA9B060100000018FC9B0601000000
BF0F3123B21A60E5AB7615AD06EA16A2BD44D84CED4DCC10AA0413127F87DC60
?1#?`?v????D?L?M????`
205BC07DA67F0000AB7615AD06EA16A2885A6C0B01000000185C6C0B01000000
BF0F3123B21A60E5AB7615AD06EA16A2BD44D84CED4DCC10AA0413127F87DC60
?1#?`?v????D?L?M????`
205BC06EB47F0000AB7615AD06EA16A288DAAE090100000018DCAE0901000000
BF0F3123B21A60E5AB7615AD06EA16A2BD44D84CED4DCC10AA0413127F87DC60
?1#?`?v????D?L?M????`
205BC0F9EB7F0000AB7615AD06EA16A288DAF5010100000018DCF50101000000
The second line is the same every time, so I know the problem is with the hexlify function and/or the Crypto++ HexEncoder. Also, the section AB7615AD06EA16A2 always matches in both seed and s. The section that does match goes from the 17th character to the 32nd character. That always happens for every seed I try. But everything else is usually different.
I don't understand why it's not encoding the bytes into a hex string properly. And I don't understand why it rarely does work even if I made no changes to the code. And I especially don't understand how the output can be different every time I run the same compiled code. What is going on here?
void unhexlify(std::string hex_string, CryptoPP::byte* &bytes)
{
std::string decoded;
CryptoPP::StringSource ss(hex_string, true, new CryptoPP::HexDecoder(new CryptoPP::StringSink(decoded)));
std::cout << decoded + "\n"; // For testing
bytes = (CryptoPP::byte*)decoded.data(); // <--
}
You return the pointer to the buffer owned by the local variable decoded that dies after function exit. You get the undefined behavior with following passing the dangling pointer to hexlify. To fix the issue return string from std::string unhexlify(std::string hex_string) and call hexlify(bytes.data(), s. bytes.size()).
This function looks suspicious:
void unhexlify(std::string hex_string, CryptoPP::byte* &bytes)
{
std::string decoded;
// stuff added to decoded, maybe...
bytes = (CryptoPP::byte*)decoded.data();
}
decoded is a local variable that is destroyed as the function exits, but you're making bytes point to the internal data of it, causing a dangling pointer (which is undefined behavior, and differing output is explained by that.)
You should just return decoded as the return value (by value), and store it on the caller's stack. Then set bytes to its data after this function returns in the calling code.

C++ File Input/Output Outputting Numbers Instead of Chars

I have created a program that randomly assigns roles(jobs) to members of a certain house using file input / output.. It builds successfully, but when using cout and I actually see the results, I can see why the program is not working.
Here is the snippet of code I believe something is wrong with :
std::string foo = std::string("Preferences/") + std::to_string(members[random]) + "-Preferences";
cout << foo << endl;
And here is the members[random] array, it is randomly selecting members from this array and reviewing their available times and assigning them jobs based on their Preference input file.
unsigned const char members[22] =
{ 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v' };
I have created a random number picker that goes through 0-21 and assigns the value it creates to variable random. So, in essence, it is members[random] and completely random.
Here is the output I get in my terminal.
Preferences/116-Preferences
But I set the output to do Preferences/ member[random] -Preferences.
It is accessing a number and not my array chars.
I created a cout << members[random]; right below it, and every time I run the program, I get
Preferences/107-Preferences <---- A random number every time
k <---- random letter every time.
So I know it must be accessing my random functions, but assigned it to numbers! How do I fix this so my proper output can be :
Preferences/t-Preferences
Please help me, and thanks!
"The more you overthink the plumbing, the easier it is to stop up
the drain" - Scotty, Star Trek III
Declaring members to be unsigned chars does not accomplish anything useful. A simple char will suffice. std::string already implements an overloaded + operator that takes a char parameter, so it's much easier than you thought it would be:
const char members[22] = {
'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v' };
// ...
std::string foo = std::string("Preferences/") + members[random]
+ "-Preferences";
There is no ::std::to_string(char), only (among less close) ::std::to_string(int). So your character is actually converted to its numerical representation and you get your unwanted result.
Try instead
std::string foo("Preferences/");
foo = foo.append(1, members[random]).append("-Preferences");
Variant using string streams:
ostringstream oss;
oss << "Preferences/" << members[random] << "-Preferences";
// get your string via:
oss.str();

SEGMENTATION FAULT in C++ - Rougewave (only in linux and not in unix)

Hi I am facing memory fault with my code. I used gdb and found out where memory fault occurs. But I am not able to solve that. The lines of code where memory fault occurs is below. Please help me friends.
void CJob::print_parm_file(){
int m_nFuncid;
CCmdset* pCmdset = NULL;
const int size=1024;
char fname[80];
char dbg_buf[size]="";
unsigned int i, gotit=0;
for (i=0; i < entries(); i++)
{
pCmdset = (CCmdset*) at(i);
//RWCollectableString *cmdset = (RWCollectableString *)pCmdset->at(0);
//RWCString m_Function=cmdset->data();
CXmlobj *xobj = (CXmlobj *)pCmdset->at(0);
cout <<"The value of m_name.data() //segfault issue is : " << xobj->m_name << endl;
cout <<"The value of m_name.data() //segfault issue is : " << xobj->m_name.data() << endl;
RWCString m_Function=xobj->m_name.data(); //segmentation fault occurs in this line
I have printed the value of m_name.data() to check its value. when i tried printing its value, segmentation fault occured in cout statements itself.
NOTE : This issue is happening only in Linux server. The code is working perfect in Unix server without any issue.
Please help me ! Thanks !!!
My educated guess is that m_name is of type std::string. There is no guarantee that a null character terminates the character sequence pointed by the value returned by data(). Simply put, your prints may access more elements than that string actually contains which causes this segmentation fault.
Try adding a \0 character at the end of the string, or replace data() with c_str() which is guaranteed to be null-terminated.
Did you first establish that xobj is valid?
CXmlobj *xobj = (CXmlobj *)pCmdset->at(0); // if xobj is invalid
xobj->m_name.data(); // ... then this will invoke undefined behavior
The simplest thing to try is just assign that string variable to a temporary string variable and see what happens. If you still get a segmentation fault, then the problem is more than likely that xobj is not pointing to a valid CXmlobj.

VC++ function string::c_str(): the address of the first byte was set to 0 (compare to g++)

I met a strange problem when trying to get the result of a string’s function c_str() whose result is inconsistent with g++.
There is a function called Test to return a string instance. And I want to use a char* type to store the result (it’s needed). As you can see the function is simple return a string “resultstring”. But when I try to get the result something strange happened.
The result I got is “” in part two. The part one and part three both return the “resultstring”. While that’s in Visual Studio. The three part of the same code compiled with g++ both return the “result string. Let’s just as well see the result first:
result of vs:
address:16841988
resultstring
address:16842096
"here is a empty line"
address:16842060
address:16842144
address:16842396
address:16842396
resultstring
result of g++
address:5705156
resultstring
address:5705156
resultstring
address:5705156
address:5705196
address:5705156
address:5705156
resultstring
The code is very simple list below:
#include <iostream>
#include <string>
using namespace std;
string Test()
{
char a[64] = "resultstring";
return string(a);
}
int main(void)
{
//part one
cout << "address:"<< (unsigned)Test().c_str() << endl;
cout << Test().c_str() << endl;
//part two
char *j = const_cast<char*>(Test().c_str());
cout << "address:"<< (unsigned)Test().c_str() << endl;
cout << j << endl;
cout << "address:" << (unsigned)j <<endl;
//part three
string h3 = Test();
char* j2 = const_cast<char*>(h3.c_str());
cout << "address:"<< (unsigned)Test().c_str() << endl;
cout << "address:"<< (unsigned)h3.c_str() << endl;
cout << "address:" << (unsigned)j2 <<endl;
cout << j2 <<endl;
getchar();
return 0;
}
Now I have three questions.
1st, why the result complied by g++ returns all resultstring while the result of Visual Studio returns all resultstring except for variable j? If you debug into this you’ll find that VC++ only set the address of j2 like 00 65 73 75 … which is esultstring with a 00 begin address. And it is not strange that we’ll get “”. It’s just like char* str = "\0something else" you’ll always get "". But the question is why does this happen only with j?
2nd, why does one of the addresses of the (unsigned) Test ().c_str() is different with others? If we remove the line string h3 = Test () the address will be all the same.
3rd, Is it the “correct” behavior of Visual Studio returning “” value of variable j? why it is different with g++?
Looking forward to your replies.
Regards,
Kevin
This is totally flawed. You create and destroy a temporary string every time you call Test(). Any attempt to access memory using pointer returned by Test().c_str() after temporary was destroyed makes no sense - memory was freed already. It MIGHT have the old values (if nothing is written there before the access), but it might have anything as well (if it is reused before the access). It's Undefined Behavior.
In case of VC++ it is overwritten once and is not in other cases. With GCC - it's never overwritten. But this is pure chance. Once again - it's UB.
You have undefined behavior. The std::string returned by Test() is a temporary and the pointer returned by c_str() (stored in j) is no longer valid after the lifetime of the temporary ends. This means that anything can happen. The array the pointer points to may contain garbage, it may be the original string or the implementation may have null terminated the beginning of it. Accessing it may cause a segmentation fault or it may allow you to access the original string data. This can and usually does vary between different compilers and implementations of the standard library.
char *j = const_cast<char*>(Test().c_str());
// The contents pointed to by j are no longer valid and access that content
// is undefined behavior
cout << "address:"<< (unsigned)Test().c_str() << endl;
The address is different between calls to Test() because it returns a temporary each time you call it. Some compilers may optimize this and/or the allocation of data may get the same block of memory but it is not guaranteed to be the same.

String concatenation issue in C++

I am trying to concatenate some string but it works in one but not another.
Working: I take in 2 argument and then do this. a = hello, b = world
string concat = a + b;
The output would be hello world with no problem.
Not working: I read from file and concatenate with 2nd argument. assuming string from file is abcdefg.
string concat = (string from file) + b;
and it gives me worldfg.
Instead of concatenating, string from b overwrites the initial string.
I have tried a few other methods such as using stringstream but it doesn't work as well.
This is my code.
int main (int nArgs, char *zArgs[]) {
string a = string (zArgs [1]);
string b = string (zArgs [2]);
string code;
cout << "Enter code: ";
cin >> code;
string concat = code + b;
}
// The output above gives me the correct concatenation.
// If I run in command prompt, and do this. ./main hello world
// then enters **good** after the prompt for code.
// The output would be **goodworld**
However, I read some lines from the file.
string f3 = "temp.txt";
string r;
string temp;
infile.open (f3.c_str ());
while (getline (infile, r)) {
// b is take from above
temp = r + b;
cout << temp << endl;
}
// The above would give me the wrong concatenation.
// Say the first line in temp.txt is **quickly**.
// The output after reading the line and concatenating is **worldly**
Hope it gives more clear example.
Update:
I think I may have found out that the problem is due to the text file. I tried to create a new text file with some random lines inside, and it seem working fine. But if I try to read the original file, it gives me the wrong output. Still trying to put my head around this.
Then I tried to copied the content of the original file to the new file, and it seem to be working fine. Not too sure what is wrong here though. Will continue to test out, and hopefully it works fine.
Thanks for all the help! Appreciate it!
I get the same output as the chap who asked the original question:
$ ./a.out hello world
Enter code: good
goodworld
worldly
The problem here is the contents of the text file. For my example, the initial 7 characters in the text file are: "quickly". However, immediately following that are 7 backspace bytes (hex 08). This is what the contents looks like in emacs:
quickly^H^H^H^H^H^H^H
So how is this causing the mess?
Well the concatenation operation actually works correctly. If you do:
std::cout << "string length: " << temp.size() << "\n";
...you get the answer 19 which is made up of: "quickly" (7) + 7 backspace chars + "world"(5). The overwriting effect you observe is caused when you print this 19 char string to console: it is the console (eg xterm) that interprets the backspace sequence as meaning "move the cursor back to the left", thus removing earlier characters. If instead you pipe the output to file, you will see the full string (including the backspaces) is actually generated.
To get around this you might want to validate/correct the input that comes from the file. There are functions commonly available in C/C++ environments such as isprint(int c), iscntrl(int c) that you could make use of.
Update: as mentioned by another responder, other ASCII control characters will also have the same effect, eg, a carriage return (Hex 0D) will also move the cursor back to the left.
If I compile this
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main (int nArgs, char *zArgs[]) {
string a = string (zArgs [1]);
string b = string (zArgs [2]);
string code;
cout << "Enter code: ";
cin >> code;
string concat = code + b;
// The output above gives me the correct concatenation.
//However, I read some lines from the file.
ifstream infile;
string f3 = "temp.txt";
string r;
string temp;
infile.open (f3.c_str ());
while (getline (infile, r)) {
temp = r + code;
cout << temp << endl;
}
// The above would give me the wrong concatenation.
infile.close();
return 0;
}
it compiles and runs flawlessly. What does this do on your computer? If it fails, we may have to compare the contents of our temp.txt.
(This ought to be a comment rather than an answer, but it's too long. Sorry.)