Ошибка сегмента в getaddrinfo()

Я получаю ошибку сегментации при вызове getaddrinfo и не могу понять, почему. Это происходит как на моем сервере, так и на клиенте. Некоторый код (на стороне сервера) -

class TcpServer {
public:

    TcpServer(int);
    ~TcpServer();

    void launchServer();

    void communicate();

private:
    const char* port;
    int fd;
    int comm_fd;
};

в tcpserver.cpp-

void TcpServer::launchServer() {
    int status;

    struct addrinfo hints;
    struct addrinfo *servinfo;  //will point to the results

    //store the connecting address and size
    struct sockaddr_storage their_addr;
    socklen_t their_addr_size;

    //socket infoS
    memset(&hints, 0, sizeof hints); //make sure the struct is empty
    hints.ai_family = AF_INET;  //local address
    hints.ai_socktype = SOCK_STREAM; //tcp
    hints.ai_flags = AI_PASSIVE;     //use local-host address

    //get server info, put into servinfo
    if ((status = getaddrinfo("127.0.0.1", port, &hints, &servinfo)) != 0) {
        fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
        exit(1);
    }

в основном-

TcpServer server(4950);
server.launchServer();

Переданное в конструктор значение int преобразуется в значение const char* для порта.

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

#0  0xb7dca737 in getaddrinfo (name=0x8054824 "127.0.0.1", 
    service=0x1356 <Address 0x1356 out of bounds>, hints=0xbffff20c, 
    pai=0xbffff234) at ../sysdeps/posix/getaddrinfo.c:2080
#1  0x08050f79 in TcpServer::launchServer (this=0xbffff304) at tcpserver.cpp:25
#2  0x0804eae9 in main (argc=1, args=0xbffff3f4) at mainserver.cpp:47

Итак, «Адрес 0x1356 вне границ» заставляет меня думать, что что-то не так с портом, но я не знаю, что может быть не так. Если кто-то может указать на что-то неправильное, я был бы признателен. Спасибо за любую помощь.


person Sterling    schedule 19.07.2011    source источник
comment
Смешать два языка в одном и том же исходном файле сложно. Я предлагаю вам придерживаться одного из C или C++ в ваших проектах.   -  person pmg    schedule 20.07.2011
comment
Ваш аргумент port для getaddrinfo неверен. Как вы инициализируете член port вашего класса TcpServer?   -  person nos    schedule 20.07.2011
comment
@pmg Он использует C, потому что скопировал необходимый код со страницы руководства.   -  person Ariel    schedule 20.07.2011
comment
@nos: он действительно упомянул, как (и вы правы, он сделал это неправильно). Я выделил эту часть жирным шрифтом, чтобы было понятнее, в чем ошибка.   -  person Evan Teran    schedule 20.07.2011
comment
@Sterling: в правильном коде должно быть очень мало приведений. Избегайте кастинга, насколько это возможно, это точная причина вашей проблемы здесь. К сожалению, эта привычка вырабатывается у многих людей, когда они узнают об указателях :-/.   -  person Evan Teran    schedule 20.07.2011
comment
@Ariel: моему компилятору не нравится ~ перед идентификатором или public:, private: вне переключателя. Тоже давится на class и на :: :)   -  person pmg    schedule 20.07.2011


Ответы (3)


getaddrinfo("127.0.0.1", port, &hints, &servinfo)
                          ^

Это должно быть char *. Я предполагаю, что вы передаете целое число и заставляете библиотеку обращаться к недопустимому адресу.

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

В свете комментария Благовеста Буюклиева я полагаю, что вы делаете что-то вроде этого в конструкторе: this->port = (const char*) port.

Вам нужно что-то использовать (может быть, snprintf?), чтобы преобразовать это целое число в char *. Простое приведение не годится.

person cnicutar    schedule 19.07.2011
comment
@Blagovest Buyukliev Я думаю, что он инициализирован неправильно (с использованием =) - person cnicutar; 20.07.2011
comment
@Blagovest Buyukliev: я выделил жирным шрифтом ту часть, где он указывает, как он инициализировал член port (и действительно, здесь ошибка). - person Evan Teran; 20.07.2011
comment
@Evan: это важная деталь, которую я упустил :-) - person Blagovest Buyukliev; 20.07.2011
comment
@Evan Teran Действительно, похоже, это так. - person cnicutar; 20.07.2011

Вы должны передавать port по ссылке, а не по значению, то есть &port? 0x1356 — это то же значение, что и 4950 — номер порта, который вы пытаетесь использовать.

edit: Хорошо, я вижу, что это должна быть строка, а не указатель на целое число. Я оставлю свой ответ на месте, так как он показывает, что значение порта неправильно интерпретируется как адрес.

person Graham Borland    schedule 19.07.2011

Вы устанавливаете указатель на порт, но не выделяете для него память. (По крайней мере, не то, что я вижу в коде, который вы указали.)

Порт должен быть строкой (т.е. массивом символов), а не указателем на символ. И не целое число.

person Ariel    schedule 19.07.2011