Вызвано исключение: нарушение прав доступа при записи

Есть ТСР сервер со студентами (студенты описаны в классе).

Пытаюсь вывести всех студентов, передавая на сервер 1. Это не работает:

Вызвано исключение по адресу 0x0101D2E9 (msvcr100d.dll) в pr1_server.exe: 0xC0000005: нарушение прав доступа при записи по адресу 0x01220000

Когда передаю на сервер 2 - работает, выводя мне студентов без троек:

введите сюда описание изображения

В чем может быть проблема? При практически идентичной логике, одно - работает, другое вообще не работает...

Код сервера:

class Student // класс описывающий студента
{
public:
    string name;
    string group;
    int stipendia;
    string mark;

    Student()
    {
        name = "";
        group = "";
        stipendia = 0;
        mark = "";
    }
    Student(string n, string g, int s, string m)
    {
        name = n;
        group = g;
        stipendia = s;
        mark = m;
    }
};
Student mas[5]; // массив из 5 объектов класса

DWORD WINAPI ThreadFunc(LPVOID client_socket)
{
    SOCKET s2 = ((SOCKET*)client_socket)[0]; //создаем сокет
    char buf[100];
    char buf1[100];
    while (recv(s2, buf, sizeof(buf), 0))
    {
        if (buf[0] == '1') { // список студентов
            string res = "";
            for (int i = 0; i < 5; i++) {
                res += (mas[i].name + " Group: " + mas[i].group + " Mark: " + mas[i].mark + "\n"); //результируящая строка содердит информацию о студенте
            }
            strcpy(buf1, res.c_str()); //конвертация в char
            strcpy(buf, buf1);
            cout << buf << endl;
        }
        
        if (buf[0] == '2') { // студенты без троек
            string res = "";
            for (int i = 0; i < 5; i++) {
                if ((mas[i].mark == "4") || (mas[i].mark == "5")) {
                    res += (mas[i].name + " Group: " + mas[i].group + " Mark: " + mas[i].mark + "\n"); //результируящая строка содердит информацию о студенте
                }
            }
            strcpy(buf1, res.c_str()); //конвертация в char
            strcpy(buf, buf1);
            cout << buf << endl;
        }
        send(s2, buf, 100, 0); //отправляем результат
    }
    closesocket(s2); //закрываем сокет
    return 0;
}

int numcl = 0;

void print() //выводим информацию про подсоединение клиента
{
    if (numcl) printf("%d client connected\n", numcl);
    else printf("No clients connected\n");
}

int _tmain(int argc, _TCHAR* argv[])
{
    setlocale(LC_ALL, "");

    mas[0] = Student("Ivanov", "Rpz 1", 900, "5"); //создаем студентов
    mas[1] = Student("Vasilev", "Rpz 1", 1100, "3");
    mas[2] = Student("Vanat", "Rpz 2", 875, "4");
    mas[3] = Student("Tomin", "Rpz 1", 900, "5");
    mas[4] = Student("Makarov", "Rpz 2", 1100, "3");

    WORD wVersionRequested;
    WSADATA wsaData;
    int err;
    wVersionRequested = MAKEWORD(2, 2);
    err = WSAStartup(wVersionRequested, &wsaData);
    if (err != 0) { return 0; }
    SOCKET s = socket(AF_INET, SOCK_STREAM, 0); //создаем сокет

    sockaddr_in local_addr;
    local_addr.sin_family = AF_INET; //тип сокета
    local_addr.sin_port = htons(1280); //порт
    local_addr.sin_addr.s_addr = 0;
    bind(s, (sockaddr*)&local_addr, sizeof(local_addr));    //шаблонная функция, возвращающая обёртку над callable-объектом
    int c = listen(s, 5);           // запуск сервера
    cout << "Server receive ready" << endl;
    cout << endl;

    SOCKET client_socket;
    sockaddr_in client_addr;
    int client_addr_size = sizeof(client_addr);
    while ((client_socket = accept(s, (sockaddr*)&client_addr, &client_addr_size))) //функция ожидания запроса
    {
        numcl++;
        print();
        DWORD thID;
        CreateThread(NULL, NULL, ThreadFunc, &client_socket, NULL, &thID); //функция ответа
    }

    return 0;
}

Ответы (1 шт):

Автор решения: EOF

В функции ThreadFunc Вы формируете строку res в цикле, а затем копируете её в буфер, размер которого всего 100 байт. Вы никак не проверяете, вмещается ли строка в этот буфер. Скорее всего strcpy просто выходит за границу массива.

→ Ссылка