Hi,

I am getting "Segmentation fault" error in line number in the following function.

deque <string> text;
deque <string> text_1;

int circuit::writetofile(int maxno,char *fname)
{
	/* Before writing the clauses correct the line p cnf */
	//deque<string> text;
	std::string s,t;
	
	/* Counting the number of original clauses in the file */
	ifstream file_cnf;
	int size_c = 0;

	/* Count the number of lines in the file */
	string linec;
	linec.clear();
	s.clear();
	t.clear();
	file_cnf.open(fname,ios::in);
	if (!file_cnf.is_open())
	{
		cout<< "Error opening file" << "\n";
		exit(-1);
	}
	else
	{
		fprintf(stderr,"I am here C \n");
		while(getline(file_cnf,linec))
		{
			size_c++;
		}

	 	fprintf(stderr,"I am here D \n");
		file_cnf.clear();
		file_cnf.close();
		cout <<"----------------Writetofile()--------------- \n" << endl;
		printf("File contains lines = %d \n",size_c);
	}

	int temp2 = (size_c-11)+columns.size();
	std::string t1;
	std::string t2;
	std::string t3 = "p cnf";
	std::string t4 = " ";
	std::stringstream outstring1;
	std::stringstream outstring2;
  
	outstring1 << maxno;
	outstring2 << temp2;
  
	t1 = outstring1.str();
	t2 = outstring2.str();

	cout << "\n" << "Number of lines after adding clauses : " <<    temp2 + 11 << "\n" << endl;
	t = t3 + t4 + t1 + t4 + t2;

	/* Changing the line */
	// load the file
	ifstream inf(fname);  // You must supply the proper filename
	if (!inf)                                       // Check for errors here
	{  
        // Print an error and exit  
        cerr << "The sequential file s298.cnf cannot be opened for reading!" << endl;  
        exit(1);  
	}

	fprintf(stderr,"I am here A \n");
	cout << "text.size() = " <<text.size() << "\n";
 while (getline( inf, s ))
		text.push_back( s );
 
	fprintf(stderr,"I am here B \n"); 
	if (!inf.eof())         // and here
	{  
        	// Print an error and exit  
       		cerr << "No end of file!" << endl;  
        	exit(1);  
	}
	inf.close();

	//erase the text
	text.erase(text.begin() + 10);

	// modify the text
	text.insert(text.begin() + 10,  // again, you must supply the line number
       string(t)
       );

	// rewrite the new text to file
	ofstream outf(fname);
	if (!outf)
	{  
        // Print an error and exit  
        cerr << "The sequential file s298.cnf cannot be opened for reading!" << endl;  
        exit(1);  
	}
	for (deque <string> ::iterator
       line  = text.begin();
       line != text.end();
       ++line)
        outf << *line << '\n';
	outf.close();

	// clearing deque
	while(!text.empty())
	{
		text.pop_back();
	}
       // deallocating memory
        deque<string>(). swap(text);
}

This function is called from some other function many times. The segmentation fault occurs at line number "while (getline( inf, s ))" marked in green, when this function is called ith time where i is around 1000.

I think there is some issue in deque. Am i deallocating the memory used by deque correctly? Should i clear the string? Should i use vector?

When I debug the function and do a backtrace i get the following error:

#0  0xb759cb36 in std::__default_alloc_template<true, 0>::allocate(unsigned) () from /usr/lib/libstdc++.so.5
#1  0xb75a2b68 in std::string::_Rep::_S_create(unsigned, std::allocator<char> const&) () from /usr/lib/libstdc++.so.5
#2  0xb75a2c99 in std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned) () from /usr/lib/libstdc++.so.5
#3  0xb75a0a06 in std::string::reserve(unsigned) () from /usr/lib/libstdc++.so.5
#4  0xb75a0fac in std::string::append(unsigned, char) () from /usr/lib/libstdc++.so.5
#5  0xb7592a42 in std::basic_istream<char, std::char_traits<char> >& std::getline<char, std::char_traits<char>, std::allocator<char> >(std::basic_istream<char, std::char_traits<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, char) () from /usr/lib/libstdc++.so.5
#6  0xb7592ab8 in std::basic_istream<char, std::char_traits<char> >& std::getline<char, std::char_traits<char>, std::allocator<char> >(std::basic_istream<char, std::char_traits<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&) () from /usr/lib/libstdc++.so.5
#7  0x080549a4 in circuit::writetofile(int, char*) (this=0x80827e0, maxno=426,

I cannot understand anything from it. Can someone please help me with it. I am stuck...

Thanks

First, why are you mixing C and C++ style file handling (I/O in general) in the same program? You are already using cerr and file streams so my strong advice is just stick with it and drop the C style file printing and error logging.

Second, I'm not sure what this:

// deallocating memory
deque<string>(). swap(text);

is trying to do. I've never seen that syntax before. If you are trying to clear the entries of a deque then call the clear() method on the deque you want to clear. Don't attempt to deallocate memory, the STL deque class will take care of that for you. You can resize the deque (if you are concerned with memory issues) using the resize() method.

deque<string>(). swap(text); It's a very radical method to deallocate memory occupied by STL container. The point is that it's unclear (in the current C++ Standard) if the clear(;)) method makes capacity == 0 (i.e. really deallocate memory, not only set the size of container to zero).

This expression statement creates an empty deque object then swap its contents with text object (to be cleared) then destroyed this new object with all its contents (obtained from the text object). Now we have an empty text object and no reserved memory resourses.

It looks clumsy but is correct and effective...

First, why are you mixing C and C++ style file handling (I/O in general) in the same program? You are already using cerr and file streams so my strong advice is just stick with it and drop the C style file printing and error logging.

Second, I'm not sure what this:

// deallocating memory
deque<string>(). swap(text);

is trying to do. I've never seen that syntax before. If you are trying to clear the entries of a deque then call the clear() method on the deque you want to clear. Don't attempt to deallocate memory, the STL deque class will take care of that for you. You can resize the deque (if you are concerned with memory issues) using the resize() method.

I tried using vector instead of deque and i am clearing the vector using clear() method and then resizing it to 0 using the resize() method. But I am still getting the error. Is there any other thing i can look into.

The file has 1500 lines and when it reads the line number 891 in the file it gives me this error:

"Program received signal SIGSEGV, Segmentation fault.
0xb759cb36 in std::__default_alloc_template<true, 0>::allocate(unsigned) () from /usr/lib/libstdc++.so.5
(gdb) n
Single stepping until exit from function _ZNSt24__default_alloc_templateILb1ELi0EE8allocateEj, 
which has no line number information."

I think the string s is overflowing. Should i clear the string after reading every line in the file 'inf' or read the file in some other way.

string s;
while (getline( inf, s ))
		text.push_back( s );

Any help is appreciated.

Thanks

That's not the point: it's impossible to overflow std::string (use max_size() member function to get a max size of std::strings in your STL implementation; I think it's ~4*10^9 bytes)...

Probably the memory was corrupted in other code...

Your stack trace clearly shows the string allocator blowing up. But how is that possible? Sadly anything is possible with undefined behavior. You could zip your source and attach it.

This article has been dead for over six months. Start a new discussion instead.