Вектор указывает на неинициализированные байты при использовании в вызове recvfrom - PullRequest
3 голосов
/ 04 января 2011

В функции, которую я пишу, я пытаюсь вернуть указатель на вектор беззнаковых символов.Соответствующий код ниже.

std::vector<unsigned char> *ret = new std::vector<unsigned char>(buffSize,'0');
//Due to suggestions...
int n = recvfrom(fd_, ret, buffSize, &recvAddress, &sockSize);
//Forgot to include this in the original
ret->resize(n);
// display chars somehow just for testing
for(std::vector<unsigned char>::iterator it=ret->begin(); it<ret->end();it++)
{
    std::cout<<*it;
}
std::cout<<std::endl;
...
return ret;

Когда я запускаю это через valgrind, я получаю ошибки, говорящие о том, как буфер в recvfrom указывает на неинициализированные байты.Я сузил это до вектора, так как я поменял его на массив без знака, и все работает отлично.Любые предложения?

Редактировать 1: Исправлена ​​часть кода, делала это из памяти / заметок с проблемой, с которой я столкнулся на работе.Причиной, по которой я начал использовать valgrind, было то, что в этом месте я получил ошибку сегментации.Я дважды проверю, что я делал завтра.

Ответы [ 2 ]

7 голосов
/ 04 января 2011

Эта строка неверна:

int n = recvfrom(fd_, ret, buffSize, &recvAddress, &sockSize);

Должно быть:

int n = recvfrom(fd_, &(*ret)[0], buffSize, 0, &recvAddress, &sockSize);

Вы читаете данные непосредственно в структуру данных std::vector, которая обычно состоит из 3 указателей (начало, конец и конец хранилища). Итак, вы перезаписываете эти 3 указателя данными, полученными через сокет, а затем перезаписываете случайную память после вектора. Компилятор не жалуется, потому что любой тип указателя (в данном случае std::vector<char> *) неявно преобразуется в void* (второй параметр в recvfrom).

Вы, конечно, хотите прочитать данные в буфер, на который указывает вектор, который получается путем взятия адреса его первого элемента, а именно &(*ret)[0]. Мы должны добавить неудобные скобки, потому что скобки [] имеют более высокий приоритет оператора, чем унарный оператор разыменования *.

(Также обратите внимание, что вы пропускаете параметр flags для recvfrom() - я предполагаю, что это была просто ошибка транскрипции при написании этого вопроса, и сейчас я установил здесь значение 0. ) * * тысяча двадцать-один

0 голосов
/ 04 января 2011

recvfrom() записаны только байты до n, но вы читаете весь буфер как выделенный. Я не уверен, что Вальгринд действительно такой умный.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...