2015-01-12 4 views
1

Я хранения C++ const char* в структуры, определенной в заголовке, как это:Одд Поведение в Struct массив символов

struct Info { 
    const char* data; 
}; 

Я тогда экземпляр структуры в заголовке класса:

class System { 
    Info info; 
} 

Я его так:

info.data = myStr.c_str(); 

Я затем распечатать его несколько раз, как это:

std::cout << info.data; 

Однако странно, что первые два раза я его распечатываю, он отлично работает, отображая правильную строку. Однако третий раз я это делаю, я получаю это:

Output: ��� 

С трех случайных двоичных символов байт (вопросительные знаки).

Я не касаюсь переменной между каждой печатью. Любая идея, почему это происходит?

+0

Что происходит между различными отпечатками 'info.data'? Почти наверняка делается что-то незаконное или «неопределенное», которое вызывает непреднамеренное изменение либо указателя, либо строки. – wallyk

+0

@wallyk Ничего не происходит с этим, но что вы думаете о ответе J Trana? Я думаю, что c_str() удаляется. Нужно ли мне делать копию буфера c_str? –

+0

Да, но что еще происходит? Почти наверняка есть написанный дикий указатель или написанный для него элемент массива вне пределов. – wallyk

ответ

2

Возможно, вы уже приняли это решение, но почти каждый раз, когда это происходит со мной, это потому, что я не наблюдал объем строки, которую я вызывал .c_str(). Константа char * не сохраняется после того, как строка умирает, и вы получите это поведение.

+0

Это имеет смысл. Как предотвратить освобождение const char *? –

+0

К сожалению, насколько я знаю, вы не можете - вам нужно сделать копию самостоятельно. –

+1

Хорошо, и вы можете сделать это вот так: 'char * cstr = new char [str.length() + 1]; std :: strcpy (cstr, str.c_str()); 'Спасибо! –

0

c_str() return - это указатель на буфер, управляемый объектом типа данных myStr. Он будет освобожден, когда строка будет уничтожена, после чего указатель больше не будет действителен. Указатель также будет недействителен, если вы измените строку. Хотя вы уже упоминали, что ничего не делаете между каждым выходом, но кто знает, что произошло на самом деле в памяти, поэтому я бы предложил вместо указания указателя на info.data скопировать значение myStr в info.data.