Valgrind result explaination - c++

i have a part of code in a bigger program that when and when i use the part that i ran trough valgrind i get seg faults later in the program.
I isolated the call to function that does some TAG manipulations. Can someone explain to me if this output is problematic?
[http://pastebin.com/5J6PHxSs][1]
and this is the code:
std::string Tag::GetDataAsString()
{
if(IsDataAvailable() <=0)
return "";
std::string retData="";
std::vector<byte>& tmp = *this->Data;
for(int i=0, length = tmp.size(); i!=length; ++i)
{
if(tmp[i] != 0x00)
retData+=tmp[i];
else
break;
}
return retData;
}
Edit 1
To explain:
Data is: std::vector* Data which is allocated when needed.
std::vector& tmp = *this->Data; // this is only that they probably did not use () :D
I'm just trying to make some code work that someone else wrote.
What i know that in the main() method Settings::GetInstance() is called which reads from file some data that is written in tags. Tag is a class that does manipulation of tags, which can be nested or contain data, thats why i believe there is a dynamic alocation of Data and Vector of sub tags.
So what happens, there is a method:
LoadFromTaggedDump( TagCollection & coll )
{
SomeData scr;
Tag* someTag;
std::vector<SomeData*>& tmpVect = *_localizedSomeDb;
for(int id = 0, dbLen = tmpVect.size(); id != dbLen; ++id)
{
Tag* tmp;
someTag= coll.GetTag(SOME_TAG | id);
if(someTag== NULL)
continue;
tmpVect[id]->SomeDat[i]=tmp->GetDataAsString();
}
}
So valgrind finds some losses in GetDataAsString() which is enclosed and should be all cleared.
And i don't understand why there would something be lost in the operator new?

Related

Another C++ strange segmentation fault by object creation

I've recently encountered a problem in c++ object creation. The problem is somewhat like it in question C++ strange segmentation fault by object creation, however the codes here are part of an open source project and may not have easy errors.
The object creation is called in a method and the method is called in two continuous steps.
The class is defined in strtokenizer.h as follows:
class strtokenizer {
protected:
vector<string> tokens;
int idx;
public:
strtokenizer(string str, string seperators = " ");
void parse(string str, string seperators);
int count_tokens();
string next_token();
void start_scan();
string token(int i);
};
And in strtokenizer.cpp, it is like this:
using namespace std;
strtokenizer::strtokenizer(string str, string seperators) {
parse(str, seperators);
}
void strtokenizer::parse(string str, string seperators) {
int n = str.length();
int start, stop;
if (flag) {
printf("%d\n", n);
}
start = str.find_first_not_of(seperators);
while (start >= 0 && start < n) {
stop = str.find_first_of(seperators, start);
if (stop < 0 || stop > n) {
stop = n;
}
tokens.push_back(str.substr(start, stop - start));
start = str.find_first_not_of(seperators, stop + 1);
}
start_scan();
}
int strtokenizer::count_tokens() {
return tokens.size();
}
void strtokenizer::start_scan() {
idx = 0;
return;
}
string strtokenizer::next_token() {
if (idx >= 0 && idx < tokens.size()) {
return tokens[idx++];
} else {
return "";
}
}
string strtokenizer::token(int i) {
if (i >= 0 && i < tokens.size()) {
return tokens[i];
} else {
return "";
}
}
The method that create the strtokenizer objects is as follows:
int dataset::read_wordmap(string wordmapfile, mapword2id * pword2id) {
pword2id->clear();
FILE * fin = fopen(wordmapfile.c_str(), "r");
if (!fin) {
printf("Cannot open file %s to read!\n", wordmapfile.c_str());
return 1;
}
char buff[BUFF_SIZE_SHORT];
string line;
fgets(buff, BUFF_SIZE_SHORT - 1, fin);
int nwords = atoi(buff);
for (int i = 0; i < nwords; i++) {
fgets(buff, BUFF_SIZE_SHORT - 1, fin);
line = buff;
strtokenizer strtok(line, " \t\r\n");
if (strtok->count_tokens() != 2) {
continue;
}
pword2id->insert(pair<string, int>(strtok->token(0), atoi(strtok->token(1).c_str())));
}
fclose(fin);
return 0;
}
When the read_wordmap() method is run for the first time (first read_wordmap() call), the 'strtok' object is created about 87k times and in the second time (second read_wordmap() call), the oject is expected to be run for more than 88k times. However, it will raise a error (sometime 'segmentation fault' and sometimes 'memory corruption (fast)') at about 86k times in the second method call, at the line:
strtokenizer strtok(line, " \t\r\n");
And when the code block of object creation is revised like those below, there will be no errors.
strtokenizer *strtok = new strtokenizer(line, " \t\r\n");
printf("line: %s", line.c_str());
if (strtok->count_tokens() != 2) {
continue;
}
pword2id->insert(pair<string, int>(strtok->token(0), atoi(strtok->token(1).c_str())));
It look like you have a memory corruption in your code. You should consider using a tool like valgrind (http://valgrind.org/) to check that the code does not write out of bounds.
Your revised code use heap memory instead of stack memory, which may hide the problem (even if it still exists).
By reading your code, there is several missing tests to ensure safe handling in case the provided wordmapfile has some unexpected data.
For example you do not check the result of fgets, so if the number of words at the begining of the file is bigger than the real number of words, you will have issues.
I carefully debugged my code under the suggestion of #Paul R and other friends and found it is because I haven't free memory in stack.
The codes proposed above are tiny parts of my project, and in the project a gibbs sampling algorithm is supposed to run for one thousand times(iterations).
In each iteration, old matrixes are supposed to be freed and new ones are to be "newed out". However, I forgot to free all the matrix and lists, and that's why my program corrupts.
The reason why I posted codes above is that the program will crash every time when it ran into the line:
strtokenizer strtok(line, " \t\r\n");
The object "strtok" will be run for 1000 * lines in files(with 10000+ lines). So it made me think maybe there are too many objects created and take up all of the stack memory. Even though I found there are no need to manually free them.
When debugged the program in visual studio, the monitor of memory occupancy showed a dramatic growth in each iteration and "bad_alloc" error took place every now and then. These made me realize that I forget to free some large dynamic matrix.
Thanks for you all!
And I apologise for the wrongly described question that takes up your time!

iterating vector of strings C++

The code is to read instructions from text file and print out graphic patterns. One is my function is not working properly. The function is to read the vectors of strings I've got from the file into structs.
Below is my output, and my second, third, and sixth graphs are wrong. It seems like the 2nd and 3rd vectors are not putting the correct row and column numbers; and the last one skipped "e" in the alphabetical order.
I tried to debug many times and still can't find the problem.
typedef struct Pattern{
int rowNum;
int colNum;
char token;
bool isTriangular;
bool isOuter;
}Pattern;
void CommandProcessing(vector<string>& , Pattern& );
int main()
{
for (int i = 0; i < command.size(); i++)
{
Pattern characters;
CommandProcessing(command[i], characters);
}
system("pause");
return 0;
}
void CommandProcessing(vector<string>& c1, Pattern& a1)
{
reverse(c1.begin(), c1.end());
string str=" ";
for (int j = 0; j < c1.size(); j++)
{
bool foundAlpha = find(c1.begin(), c1.end(), "alphabetical") != c1.end();
bool foundAll = find(c1.begin(), c1.end(), "all") != c1.end();
a1.isTriangular = find(c1.begin(), c1.end(), "triangular") != c1.end() ? true : false;
a1.isOuter = find(c1.begin(), c1.end(), "outer") != c1.end() ? true : false;
if (foundAlpha ==false && foundAll == false){
a1.token = '*';
}
//if (c1[0] == "go"){
else if (c1[j] == "rows"){
str = c1[++j];
a1.rowNum = atoi(str.c_str());
j--;
}
else if (c1[j] == "columns"){
str = c1[++j];
a1.colNum = atoi(str.c_str());
j--;
}
else if (c1[j] == "alphabetical")
a1.token = 0;
else if (c1[j] == "all"){
str = c1[--j];
a1.token = *str.c_str();
j++;
}
}
}
Before debugging (or posting) your code, you should try to make it cleaner. It contains many strange / unnecessary parts, making your code harder to understand (and resulting in the buggy behaviour you just described).
For example, you have an if in the beginning:
if (foundAlpha ==false && foundAll == false){
If there is no alpha and all command, this will be always true, for the entire length of your loop, and the other commands are all placed in else if statements. They won't be executed.
Because of this, in your second and third example, no commands will be read, except the isTriangular and isOuter flags.
Instead of a mixed structure like this, consider the following changes:
add a default constructor to your Pattern struct, initializing its members. For example if you initialize token to *, you can remove that if, and even the two bool variables required for it.
Do the parsing in one way, consistently - the easiest would be moving your triangular and outer bool to the same if structure as the others. (or if you really want to keep this find lookup, move them before the for loop - you only have to set them once!)
Do not modify your loop variable ever, it's an error magnet! Okay, there are some rare exceptions for this rule, but this is not one of them.
Instead of str = c1[++j];, and decrementing later, you could just write str = c1[j+1]
Also, are you sure you need that reverse? That makes your relative +/-1 indexing unclear. For example, the c1[j+1 is j-1 in the original command string.
About the last one: that's probably a bug in your outer printing code, which you didn't post.

ProtocolBuffer object ByteSize is wrong

I have the following method:
void ConnectionManager::SendAll()
{
for (int t = 0; t < (int)m_Connections.size(); ++t)
{
if (m_Connections[t].socket != INVALID_SOCKET)
{
// Create the object
MessageID message;
message.set_type(MessageID::Type::MessageID_Type_PLAYERDATA);
for (int i = 0; i < (int)m_Connections.size(); ++i)
{
if (m_Connections[i].playerData.username() != google::protobuf::internal::kEmptyString)
{
auto temp = message.add_playerdata();
temp = &m_Connections[i].playerData;
}
}
if (message.playerdata_size() > 0)
{
// Serialize to byte array
int size = message.ByteSize();
void* buffer = malloc(size);
message.SerializeToArray(buffer, size);
Send(m_Connections[t].socket, buffer, size);
}
}
}
}
Now the problem lies at the end of this method, at the line:
int size = message.ByteSize();
I know that the data is loaded correctly (or it should be at least) but the size isn't right. It should be 30 and it returns 2. I have no idea what I'm doing wrong.
The data in m_Connections is available and should be reached by pointer temp. I think that, for some reason, the data is lost from the "message" object but I don't know how to solve it.
auto temp = message.add_playerdata();
temp = &m_Connections[i].playerData;
These lines look wrong. add_playerdata() returns a pointer. That means that the second line is just setting temp to some other pointer, not doing anything to the message which temp points at. It's more obvious if you write out the type rather than use auto:
MessageID::PlayerData* temp = message.add_playerdata();
temp = &m_Connections[i].playerData;
Maybe you wanted to do this instead:
*temp = m_Connections[i].playerData;
However, I do not see how this bug would lead to ByteSize() being 2. It looks like ByteSize() should only be 2 if you haven't added any players to the message, but then playerdata_size() would be zero, so you wouldn't get to the serialization step at all.

C++ - Delete std::string*; heap corruption

I'm relatively new to C++ memory management, and I'm getting this weird error of heap corruption (plus an automatic breakpoint in Visual Studio before it). Here is the offending code:
z_world::z_world(char* name)
{
unsigned int i, skip;
char tmp;
//Load data from file
std::string* data = loadString(name);
//Base case if there is no world data
tiles = NULL;
w = 0;
h = 0;
if(data->length() > 0) {
//Set up the 'tiles' array
for(i = 0; i < data->length(); i++) {
if(data->at(i) == '\n')
h++;
if(h == 0)
w++;
}
tiles = new int[data->length()-h];
//Load Data
skip = 0;
for(i = 0; i < data->length(); i++) {
if(data->at(i) == '\n') {
skip++;
printf("\n");
continue;
}
tmp = data->at(i);
tiles[i+skip] = atoi(&tmp);
printf("%i ",tiles[i+skip]);
}
}
delete data;
}
Here's where I load in the string:
std::string* loadString(char* name)
{
ifstream in(name);
std::string* input = new string();
while(in) {
std::string line;
getline(in,line);
input->append(line);
input->append("\n");
}
in.close();
return input;
}
I get the breakpoint and error inside of "delete data;", which makes me think that "data" gets deleted somewhere before that, but I can't find where it would. For reference, this method is to create an object that contains world data for a game in the form of a virtual 2D integer array (for the ID's of the tiles).
Youre problem is probably here:
tiles[i+skip] = atoi(&tmp);
Problem 1:
It should be -skip
tiles[i - skip] =
Problem 2:
The atoi() command is being used incorrectly (tmp does not contain a string). But also I don't think atoi() is the appropriate method. I think what you are looking for is simple assignment. The conversion from char to int is automatic:
tiles[i - skip] = tmp;
Problem 3:
You are not using objects correctly. In this situation there is no need to generate dynamic objects and create a mess with dynamic memory management. It would be simpler to just to create automatic objects and pass those back normally:
std::string* loadString(char* name)
// ^ Don't do this.
std::string loadString(std::string const& name)
// ^^^^^^^ return a string by value.
// The compiler will handle memory management very well.
In general you should not be passing pointers around. In the few situations where you do need pointers they should be held within a smart pointer object or containers (for multiple objects) so that their lifespan is correctly controlled.
atoi(&tmp);
atoi expects a pointer to a null terminated string - not a pointer to a char
There's no need to dynamically allocate the string in the code you've shown. Change the loadString function to
std::string loadString(char* name)
{
ifstream in(name);
std::string input;
// ...
return input;
}
In the caller
std::string data = loadString( name );
Now there's no need to delete the string after you're done.
Instead of
int *tiles = NULL;
tiles = new int[data->length()-h];
use
std::vector<int> tiles;
tiles.resize(data.length() - h);
Also, if you do need to dynamically allocate objects you should be using smart pointers (std::unique_ptr and std::shared_ptr) instead of raw pointers.
There is a bug in
tiles[i+skip] = atoi(&tmp);
For example, for a string
Hello\n
World\n
and for the loop iteration at the point of i == 10, skip is already 1 (since we have encountered the first \n before) and you are writing to tiles[10 + 1], but tiles only has been allocated as an array with 10 elements.
May be the variable input is local to this function. So after returning from this the memory is freed. So, calling later delete on this string tries to free already freed memory.

C++ std::string to char for using with OpenGL LoadBMP

I've got an string array
string name[1000];
and with
int counter;
counter = 0;
while(FindNextFile(fHandle, &wf))
{
... //some more code which is checking if its a folder
string theName = wf.cFileName;
if(theName.find(".bmp") != std::string::npos)
{
name[counter] = theName;
counter++;
}
}
I am adding each .bmp file to my name array.
Using NeHe's Tutorial I'm adding Textures to my Qubes, which is working very well.
Now my customized code looks like this:
int n; string imageFileString[1000]; char *imageFile[1000];
for(n=0; n<1000; n++)
{
imageFileString[n] = name[n];
imageFile[n] = new char[imageFileString[n].length()];
strcpy(imageFile[n], imageFileString[n].c_str());
if(TextureImage[n] = loadBMP(imageFile[n]))
{
... // Some more Functions to set textures
}
}
Everything is working well, only that my BMP Files arent loaded.
If I add
name[0] = "pic1.bmp";
name[1] = "pic2.bmp";
name[2] = "pic2.bmp";
name[3] = "pic2.bmp";
before setting the int n; string imageFileString..., so for the for(...) loop my Pictures are loaded without changing anything else. My first opinion was that the name array has no entrys, but I created a Log file with the output
name[0] << endl << name[1] << endl << name[2] ...
and in my Log file were the same names
pic1.bmp
pic2.bmp
pic3.bmp
so I think there is some other error adding the cFileName to my array.
Can anyone help me please? I dont know how to fix this, i mean I've no idea what is wrong...
imageFile[n] = new char[imageFileString[n].length()];
You're not accounting for the null-terminator. Add one to the length:
imageFile[n] = new char[imageFileString[n].length() + 1];
This isn't an answer, but it would be too hard to post in a comment.
Why are you doing all this?
int n; string imageFileString[1000]; char *imageFile[1000];
for(n=0; n<1000; n++)
{
imageFileString[n] = name[n];
imageFile[n] = new char[imageFileString[n].length()];
strcpy(imageFile[n], imageFileString[n].c_str());
if(TextureImage[n] = loadBMP(imageFile[n]))
{
... // Some more Functions to set textures
}
}
When you could just do this?
int n;
for(n=0; n<1000; n++)
{
if(TextureImage[n] = loadBMP(name[n].c_str()))
{
... // Some more Functions to set textures
}
}
Since you said everything works fine when you do name[0] = "pic1.bmp" etc, you need to print out/debug string theName = wf.cFileName; I would guess it is a pathing issue. wf.cFileName is probably returning a file path you aren't expecting.
For example I bet it's returning something like \MyData\Bitmaps\pic1.bmp where you are only expecting pic1.bmp
Update
Given all the other wonderful changes, you can also shorten it even further and do this
int counter = 0;
while (FindNextFile(fHandle, &wf))
{
if (strstr(wf.cFileName, ".bmp") != 0)
{
if(TextureImage[counter] = loadBMP(wf.cFileName)
{
... // Some more Functions to set textures
counter++
}
}
}
There isn't any reason to allocate more memory just to check if a string (".bmp") is present. Also note I don't update the counter unless the load succeeds.
You really should switch TextureImage to a std::vector then you wouldnt have to do any counting. Check to see if you pass wf.cFileName directly to your loadBMP if things work. And I do realize that this could present in an overflow due to TextureImage[] and counter which is why I suggest switching to std::vector. We don't see how he allocates TextureImage[], if it's like everything else it was with a magic number of 1000.
Also keep in mind that .cFileName is defined as TCHAR[] which can hold unicode values.
Ok I found the Problem myself,
Update, fixed version (WinMain):
void ScanTheDirectory()
{
// this function is scanning the directory and is adding
// each bmp file to the string array "name"
}
int initGL()
{
// this function calls the loadTextures() function
}
int loadTextures()
{
// this function is loading all files of the string array "name"
// converts them to a const char * and is adding them to the "textures" GLuint (array)
}
int WINAPI WinMain()
{
// this function is the main window which is showing the
// qubes (GL_QUBES)
ScanTheDirectory();
initGL();
}
The Problem was in WinMain(), because it looked like this:
initGL();
ScanTheDirectory();
If it is first calling the initGL(), so it is creating the Textures, and because the name array is empty, there are no Textures added to my Textures array.
After changing this to
ScanTheDirectory();
initGL();
Now it is first calling the ScanTheDirectory() void and so my name array is filled with names of BMP Image Files.
Now it can call the initGL and this is creating the Textures out of my Images.
Thanks for the Help, now my Code is looking a little bit clearer :D
Ahmet