0

I keep getting a SIGSEGV crash converting a std::string to char*. I have a name I wish to display in an ITextControl (WDL Framework). The following snippet works fine in some parts of my app but not here:

char * paramName = new char[name.size() + 1];
std::copy(name.begin(), name.end(), paramName);
paramName[name.size()] = '\0'; // don't forget the terminating 0
lcdToWriteParamNamesTo->SetTextFromPlug(paramName);

Following the trace....

void ITextControl::SetTextFromPlug(char* str)
{
  if (strcmp(mStr.Get(), str))
  {
    SetDirty(false);
    mStr.Set(str);
  }
}

Next step:

char *Get()
{
  if (m_hb.GetSize()) return (char *)m_hb.Get();
  static char c; c=0; return &c; // don't return "", in case it gets written to.
}

And finally CRASH!:

int GetSize() const { return m_size; }

EDIT: As requested:

void WDL_STRING_FUNCPREFIX Set(const char *str, int maxlen WDL_STRING_DEFPARM(0))
{
  int s=0;
  if (str)
  {
    if (maxlen>0) while (s < maxlen && str[s]) s++;
    else s=(int)strlen(str);   
  }
  __doSet(0,str,s,0);
}

From my limited understanding of C++ and this answer, a bounds issue could cause the SIGSEGV or writing into read-only memory.

Just to clarify, this snippet in one class ALWAYS crashes and in another class NEVER crashes, though both classes are passed the same string and ITextControl.

Can anybody help me shed some light on this?

EDIT: Suggestion to use c_str() doesn't help:

char * cstr = new char [name.length()+1];
std::strcpy (cstr, name.c_str());
lcdToWriteParamNamesTo->SetTextFromPlug(cstr);
delete[] cstr;

This also crashes.

Community
  • 1
  • 1
Dave Chambers
  • 2,483
  • 2
  • 32
  • 55
  • 5
    Why not use the provided function [`std::string::c_str()`](http://en.cppreference.com/w/cpp/string/basic_string/c_str)? – Drew Dormann May 15 '15 at 15:52
  • What is the code for `mStr.Set(str);`? – NathanOliver May 15 '15 at 15:54
  • Your problem isn't with the conversion itself, it's with what being stored in `mStr` member of `ITextControl`. – SomeWittyUsername May 15 '15 at 15:55
  • Make sure lcdToWriteParamNamesTo is propertly constructed when you call SetTextFromPlug(). The crash in the GetSize() means what 'this' pointer for m_hb is invalid. That could happen if lcdToWriteParamNamesTo point to some uninitialized memory (NULL or whatever else). – alexander May 15 '15 at 16:14
  • @alexander. I owe you all an apology. I had forgotten to initialise lcdToWriteParamNamesTo with the pointer in the initialisation list. I'm very sorry! If you make your comment an answer I'll mark it as correct since it solved my problem. – Dave Chambers May 15 '15 at 18:07

1 Answers1

1

Doesn't look like converting string is an issue.

SIGSEGV is triggered on invalid memory reference. It means when you try to read from lcdToWriteParamNamesTo->mStr->m_hb->m_size you read from not acquired memory.

One of objects is probably already destroyed or by mistake one of pointers is overwritten to point to memory not acquired:

  • lcdToWriteParamNamesTo
  • mStr
  • m_hb
  • m_size
M.L.
  • 728
  • 4
  • 12
  • Actually, this is the right answer since, as I mentioned above in the comments: I had forgotten to initialise lcdToWriteParamNamesTo with the pointer in the initialisation list. I'll mark it as correct since this is technically the correct answer – Dave Chambers May 19 '15 at 14:25