The following code works in a the Marmalade simulator (I'm on OSX using x-code)

bool PictureDictionary::OnTableSelect(CTable* table, int tab){
    //if something is selected, look up the item, and display it
    //also change the search to the selected item
    if(-1 < tab){

        // if a term is selected, set the search text field to the term
        CString term = m_SearchResults.GetString(tab);

        if(m_currentWord != (char*)term.Get()){
            m_currentWord = (char *)term.Get();
            m_searchTextField->SetAttribute("text", term);

            char* normalizedTerm = (char *)term.Get();
            char* imagePath;
            sprintf(imagePath,"images/%s.jpg", normalizedTerm);

            if(m_ImageAttached){
                m_Image->SetAttribute("image", (const char*)imagePath);
            } else {
                m_Image = CreateImage(CAttributes()
                                      .Set("name",    "picture")
                                      .Set("x1",      "0")
                                      .Set("x2", "0")
                                      .Set("y1",      "50%")
                                      .Set("image", (const char*)imagePath)
                                      );
                m_SearchView->AddChild(m_Image);
                m_ImageAttached = true;
            }
        }
    }
    return true;
}

When I run the simulator, and select an item from the table, the image appears, and changes when I select a different item. When I go to refactor, I get a EXC_BAD_ACCESS (code=1…..) Error

bool PictureDictionary::OnTableSelect(CTable* table, int tab){
    //if something is selected, look up the item, and display it
    //also change the search to the selected item
    if(-1 < tab){

        // if a term is selected, set the search text field to the term
        CString term = m_SearchResults.GetString(tab);

        if(m_currentWord != (char*)term.Get()){
            m_currentWord = (char *)term.Get();
            m_searchTextField->SetAttribute("text", term);        

            char* normalizedTerm = (char *)term.Get();
            char* imagePath;
            sprintf(imagePath,"images/%s.jpg", normalizedTerm);

            UpdatePictureView(imagePath);
        }
    }
    return true;
}

void PictureDictionary::UpdatePictureView(char* imagePath){
    if(m_ImageAttached){
        m_Image->SetAttribute("image", (const char*)imagePath);
    } else {
        m_Image = CreateImage(CAttributes()
                              .Set("name",    "picture")
                              .Set("x1",      "0")
                              .Set("x2", "0")
                              .Set("y1",      "50%")
                              .Set("image", (const char*)imagePath)
                              );
        m_SearchView->AddChild(m_Image);
        m_ImageAttached = true;
    }
}

Any suggestions on how to clean up the code without getting these issues?

Edit RE Comments about uninitialized variables: m_ImageAttached was initialized to false in the constructor, unless I'm doing something wrong. Also, changing the condition to check if m_Image!=NULL also throws the same error.

main.cpp:

PictureDictionary pictDict(myApp, &dictionary);

Constructor for PictureDictionary:

PictureDictionary::PictureDictionary(CAppPtr app,Dictionary::Dictionary* dictionary){
    m_App = app;
    m_Dictionary = dictionary;
    m_currentWord = "";
    m_ImageAttached = false;
}
有帮助吗?

解决方案

imagePath is an unitialized pointer, in both snippets. Any attempt to dereference is undefined behaviour. It just appeared to work in the first snippet. Use an array or populate a std::string instead:

std::string imagePath(std::string("images/") + normalizedTerm + ".jpg");

And use std::string::c_str() if access to the underlying const char* is required.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top