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.
Related
For the sake of me better understanding C++ strings, array and pointers; I want to know: Why is it that I can use a condition whereby I check if the index has reached the null-terminating character like this...
const char* myString = "Grandopolous";
for (int i = 0;;i++)
{
if (!myString[i])
break;
else
cout << myString[i];
}
So that works just fine. Here I am instead checking to see if the character equals something other than the null-terminating character and so I expect that if it doesn't the result should be not 0 and the condition should be true. but this does not work, and I simply cannot fathom why:
const char* myString = "Grandopolous";
for (int i = 0;;i++)
{
if (myString[i])
cout << myString[i];
}
This does not work on my machine and crashes, also it outputs a lot of unreadable error messages mixed with strange symbols. I don't think that part matters although it is the first time error have been printed to my console application instead of the debug console.
The reason I mentioned pointers is because I managed to get the condition to work using pointers instead of the array index syntax which I find much easier to read.
So could someone please help me understand why my first bit of code is valid and why my second is not.
It does work. The check for null isn't the problem.
Your program crashes because you got rid of the break so your program overruns the array then continues forever into the abyss.
Your debugger would surely have revealed this to you as you stepped through the program, observing i.
To reverse the logic of your first example, write:
const char* myString = "Grandopolous";
for (int i = 0;;i++)
{
if (myString[i])
cout << myString[i];
else
break;
}
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.
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.....
So to start off this code works on all my redhat machines and some other solaris machines. The machine that is producing the fault is a solaris 64 bit. The code I have is as follows:
This is the frUUID class:
frUUID::frUUID()
{}
std::string frUUID::genUUID()
{
char uuidBuff[36];
uuid_t uuidGenerated;
uuid_generate_random(uuidGenerated);
uuid_unparse(uuidGenerated, uuidBuff);
std::cout << uuidBuff << std::endl; // prints out a correct uuid
return std::string(uuidBuff);
}
Then in a unit test I have:
frUUID uuids;
std::string uuid1 = uuids.genUUID();
std::cout << std::endl << "UUID 1: " << uuid1 << std::endl;
//This cout produces the seg fault on the uuid1
I have no idea what is going on here everything seems to be correct? Does anyone have any ideas?
From the uuid_unparse man page:
The uuid_unparse function converts the supplied UUID uu from the internal binary format into a 36-byte string (plus tailing '\0')
Your buffer is too small for that. You're in undefined behavior territory.
You're not leaving space for the trailing null byte in uuidBuff.
change
char uuidBuff[36];
to
char uuidBuff[37];
for the null character
My C++ program compiles and works up until I call this function from main():
int uword(){fstream infile("numbers.txt");
fstream exfile("wordlist.txt");
string numb[numoflines];
string lines[numoflines];
number = 1;
line = 1;
for(int i=0;i<numofline;++i)
{
getline (infile,number);
numb[i] = number; //I think this is causing the problem
getline (exfile,line);
lines[i] = line; //This too
}
infile.close();
exfile.close();
string yourword;
Something here causes it to crash, in the debug it pops up with "An access violation (Segmentation Fault) raised in your program."
EDIT: My mistake was using !infile.eof in the for loop.
Not a direct answer, but I believe it's a good one...
Use The Debugger! GDB should suspend at the exact line when the segmentation fault happens, thus giving you a very good hint about what the error is.
The getline function does not work the way you think it works.
Also, there could be more than numoflines lines in infile.