malloc — правильно объявляет буфер для tcp-сервера Переполнение стека

Я использую TCP-сервер, который я написал для обработки входных данных в базу данных. У меня есть клиент TCP, сидящий на сервере, который отправляет имя файла на сервер TCP, сидящий на другом сервере Linux. Как только имя файла получено, сервер Linux переходит в общую папку и извлекает файл, а затем вставляет его в базу данных.

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

сейчас это работает так:

 char data[1024];

это нормально, но он не удаляет буфер полностью автоматически, поэтому я попытался неявно выделить память для «данных», таких как:

char *data = (char*) malloc(1024 * sizeof(char));
...
free(data);

ИЛИ ЖЕ

char *data = new char[1024];
...
delete[] data;

По какой-то причине вышеупомянутые две декларации объявляют буфер размером = 8, я получил это, используя

sizeof(data);

Кроме того, я получаю только 8 символов. Я не уверен, почему он делает это, любая помощь?

РЕДАКТИРОВАТЬ

char *data = (char*)malloc(1048 * sizeof(char));
if(data==NULL) exit(1);
cout << "DATA Size: " << sizeof(data) << "\n";
int msglen = read(conn, data, sizeof(data));
cout << "Server got " << msglen << " byte message: " << data << "\n";

if(write(conn, &msglen, sizeof(msglen))<0){
cout << "Failed to write back to the client " << strerror(errno);
}

free(data);
close(conn);

0

Решение

Есть несколько вещей не так с вашим кодом.
1) не используйте malloc — вы пометили свой вопрос как c ++ — используйте malloc только при необходимости, замените его на:

const int dataSize = 1024;
char *data = new char[dataSize];

2) sizeof (data), когда data является char *, возвращает 8, потому что он возвращает размер указателя, а не массива, когда вы объявляете данные как массив sizeof будет возвращать байты, занятые всем массивом. вам следует заменить прочитанное на:

int msglen = read(conn,data,dataSize)

3) Я предполагаю, что вы хотите записать данные, которые вы только что получили обратно отправителю. Затем:
в функции записи вы помещаете sizeof (msglen) в качестве третьего аргумента, который (в большинстве случаев) всегда возвращает 4. remove sizeof ().

write(conn, data, msglen);

После того, как вы закончите с данными, не забудьте очистить память, используя:

delete[] data;

использование delete[] всегда, когда вы назначили память new[],

1

Другие решения

API write(int socket, char *buf, int len);

Код становится таким:

write(con, data, msglen);
1

Предполагая, что вы не можете использовать стек (например, char buf[1024]), использование голых указателей не рекомендуется как плохой стиль и подвержены ошибкам. Вместо этого используйте RAII и некоторый вариант измененной памяти, такой как shared_ptr или же unique_ptr,

#include <memory> и использовать std::shared_ptr<>, или же std::unique_ptr<> плюс std::move() вернуть буфер:

std::size_t bufSize = 1024;
std::unique_ptr<char[]> myUniqueBuf(new char[bufSize]);
ssize_t msglen = ::read(conn, *myUniqueBuf, bufSize); // return type is ssize_t, not int
return std::move(myUniqueBuf); // If you need to return the buffer

// I think you will probably prefer a shared_ptr<> because it has a copy
// constructor which makes it easier to pass around and return from functions
std::shared_ptr<char[]> mySharedBuf(new char[1024]);
ssize_t msglen = ::read(conn, *mySharedBuf, bufSize); // return type is ssize_t, not int
ssize_t bytesOut = ::write(conn, *mySharedBuf, msglen);
return mySharedBuf;

Преимущество для std::shared_ptr или же std::unique_ptr в том, что вам не нужно беспокоиться об очистке голого указателя (т.е. delete[] data;) потому что с управляемой памятью это будет происходить автоматически для вас, когда дескриптор буфера выходит из области видимости или счетчик ссылок обнуляется (например, myUniqueBuf или же mySharedBuf).

0
По вопросам рекламы [email protected]