2013-02-13 7 views
0

У меня возникла странная проблема, которая не имеет для меня никакого смысла.Проблемы с сохранением объектов в живых

У меня есть структура (которая содержит строку) на API определяется следующим образом:

typedef struct sNCharcb 
{ 
    char * pData; 
    int iDataLen; 
} 
tsNCharcb; 

мне нужно сохранить глубокую копию этой структуры. Я создал функцию полезности, чтобы сделать копию этой структуры:

inline sNCharcb rapi_strcpy(const sNCharcb &rapistr) 
{ 
    sNCharcb res; 

    res.pData = new char[rapistr.iDataLen]; 
    strcpy(res.pData, rapistr.pData); 
    res.iDataLen = rapistr.iDataLen; 

    return res; 
} 

создать копии этих структур «sNCharcb» с помощью этого метода полезности и сохранять их ссылаться на переменные в родительском объекте:

stored_sNCharcb = rapi_strcpy(sNCharcb_to_copy); 

Спустя некоторое время эти сохраненные значения изменяются магически, чтобы содержать какой-то случайный мусор. Родительский объект, в котором хранятся эти значения, постоянно находится в пределах области действия и не разрушен. Что может привести к преждевременному стиранию этих ценностей?

+0

есть причина, почему вы не 'станд :: string' вместо этого? –

+0

Вы должны, вероятно, реализовать значимые конструкторы копирования, оператор присваивания и деструктор для этого класса. Или пометьте вопрос как C. Или просто используйте элемент данных 'std :: string' вместо' char * ', и все проблемы исчезнут. – juanchopanza

+0

Это API, который я не могу изменить. Мне нужно играть с строками C, нравится мне это или нет. –

ответ

1

Есть ли данные в pData NULL прекращено? Если нет, то вызов strcpy в rapi_strcpy может быть запущен с конца и, следовательно, копирование за пределы, выделенные в цели.

Вы, вероятно, хотите использовать что-то, что заставляет длину, как strncpy или memcpy:

strncpy(res->pData, rapistr.pData, rapistr.iDataLen); 
+0

данные должны быть NULL прекращены, однако я изменю метод, как было предложено. Это безопаснее. –

+0

Данные фактически не были завершены NULL, и rapi_strcpy убегала, как вы предлагали, и записывая части памяти, которые она не должна касаться. Это вызвало проблему и сменил метод strcpy на strncpy, чтобы заставить длину устранить проблему! –

1

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

Предполагая, что stored_sNCharcb справедливо, когда rapi_strcpy() выходит, а затем stored_sNCharcb изменения в более позднее время, что бы предположить, что код не показан перезапись stored_sNCharcb, когда оно не должно быть, например, из-за переполнения буфера или например. Я предлагаю вам поставить точку останова данных на stored_sNCharcb после выхода rapi_strcpy(), а затем позволить отладчику рассказать вам, изменяется ли он, чтобы вы могли точно видеть, какой код его модифицирует.

+0

Это оказалось хорошим способом диагностики проблемы. Это действительно переполнение буфера. –

Смежные вопросы