visual studio 2008 sp1 std :: string :: c_str () err - PullRequest
1 голос
/ 31 октября 2011

Я встречался с такой же ситуацией в моем проекте.Следующий код был воспроизведен аналогичным образом.

#include <iostream>
#include <vector>
using namespace std;


class METHOD
{
public:
vector<METHOD*> m_arg;
string name;
string getName()
{
    return name;
}
METHOD()
{

}
METHOD(string n)
{
    name = n;
}
};

class PF : public METHOD
{
public:
PF(){};
};

void main()
{


PF p;
p.m_arg.push_back(new METHOD(string("a")));
p.m_arg.push_back(new METHOD(string("b")));
p.m_arg.push_back(new METHOD(string("c")));

for(int i = 0 ; i < (int)p.m_arg.size() ; ++i)
{
    const char* ccs = p.m_arg[i]->getName().c_str();  //PROBLEM POINT

    size_t ss = strlen(ccs);
}

}

проблема в том, // ТОЧКА ПРОБЛЕМЫобратный адрес c_str () не может быть назначен на const char * ccs .в отладчике css назначил адрес памяти возврата c_str () , но значение css равно "", и оно работает так же, как ""

но следующий код работает как положено.

    string str("ok");
const char* ckk = str.c_str();

после этого кода ckk указывает после str.c_str () возвращаемых адресов, а значение ckk в отладчике равно"Хорошо"

та же проблема возникает в std :: wstring, wchar_t, unicode.

почему возникла эта проблема?кто знает?помогите мне плз ~

ДОБАВИТЬ: благодаря мистическому я решаю проблему таким же образом.но это решение также работает хорошо.

    for(int i = 0 ; i < (int)p.m_arg.size() ; ++i)
{
    string& strr = p.m_arg[i]->getName();
    const char* ccs = strr.c_str();
    size_t ss = strlen(ccs);
}

, поэтому я думаю, что возвращаемое значение getName () действует до тех пор, пока цикл не закроется.но что интересно, следующее - не работает

    for(int i = 0 ; i < (int)p.m_arg.size() ; ++i)
{
    string* strr = &p.m_arg[i]->getName();
    const char* ccs = strr->c_str();
    size_t ss = strlen(ccs);
}

css "висят", а также strr ""я ошеломлен и смущен!

1 Ответ

4 голосов
/ 31 октября 2011

В вашей функции getName():

string getName()
{
    return name;
}

Возвращаемая строка является копией оригинала.Он становится промежуточным в следующем выражении:

const char* ccs = p.m_arg[i]->getName().c_str();

Когда выражение заканчивается, это промежуточное звено уничтожается.Поэтому аннулирование указателя, возвращенного c_str(). В результате ccs становится висящим указателем.

Причина, по которой это работает:

string str("ok");
const char* ckk = str.c_str();

, заключается в том, что str не является промежуточным звеном.

Чтобы это сработало, измените ваш цикл следующим образом:

for(int i = 0 ; i < (int)p.m_arg.size() ; ++i)
{
    string str = p.m_arg[i]->getName()
    const char* ccs = str.c_str();

    size_t ss = strlen(ccs);
}

РЕДАКТИРОВАТЬ: Чтобы ответить на ваш новый вопрос:

Причина, по которой это не работает:

string* strr = &p.m_arg[i]->getName();

такая же, как и раньше.getName() возвращает промежуточное звено.Затем вы берете адрес этого и присваиваете ему strr.Промежуточное звено уничтожается после оператора, поэтому strr становится висячим указателем, как в первом случае.

...