0

在我开始使用 getaddrinfo() 检索动态 IP 地址后,我的套接字的 sendTo() 不再工作并返回错误“分段错误(核心转储)”。为什么会这样,请问我的代码中是否缺少任何初始化或内存分配?我已经尝试了一段时间,但还没有弄清楚原因。任何帮助将非常感激!

这是代码的一部分:

    // variables declaration
    int s;
    struct sockaddr_in si_other;
    struct addrinfo hints;     
    struct addrinfo *result, *rp;
    char *hostname = "localhost"; 
    const char* portnum = "8000"; 

    // settings of hints
    memset(&hints, 0, sizeof(struct addrinfo));
    hints.ai_family = AF_UNSPEC;    /* Allow IPv4 or IPv6 */
    hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
    hints.ai_flags = 0;
    hints.ai_protocol = 0;
    hints.ai_flags = AI_NUMERICSERV;

    // resolve dynamically IP adress by getaddrinfo()
    s = getaddrinfo(hostname, NULL, &hints, &result); 
    if (s != 0) {
            fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));exit(EXIT_FAILURE);
    }
    // create socket s
    for (rp = result; rp != NULL; rp = rp->ai_next) 
    {
            s = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
    }

    // loop for sending m x struct ECA_message_t 
    int m=0;
for (; m<NbMesPerFile; ++m) 
    {

            ECA_message_t* ECA_paquet;
            ECA_paquet=(ECA_message_t*)malloc(sizeof(ECA_message_t)*2400); 
            // 2400 to workaround some not understood memory issue and make sendto() to 
            // work  

            // function initializing ECA_paquet
            Client_update_ECA_data(ECA_paquet,m);
            if (sendto(s, ECA_paquet, sizeof(ECA_paquet)*2400, 0 ,(struct 
                  sockaddr*)&si_other,slen)==-1)
    {
        perror("sendto()");
    }
    }

要向我的结构添加详细信息,并找出我的 malloc(sizeof(ECA_message_t) 出错的原因,请参阅下面的 struct ECA_message_t 代码:

typedef struct{

unsigned int version:2;
unsigned int p:1;
unsigned int x:1;
unsigned int cc:4;
unsigned int m:1;
unsigned int pt:7;
unsigned int seq:16;
u_int32_t timestamp;
u_int32_t ssrc;
u_int32_t csrc;
} RTP_header_t;             // 16 bytes


typedef struct {

unsigned int version:2;
unsigned int reserved_1:6;
unsigned int reserved_2:8;
unsigned int number_sample:16;

}ECA_header_t;              // 4 bytes

typedef struct {

//every line composed of 6 values, 2 byte per value, all signed
int32_t v_phase_1;
int32_t v_phase_2;
int32_t v_phase_3;
int32_t i_phase_1;
int32_t i_phase_2;
int32_t i_phase_3;

}ECA_payload_t;             // 12 bytes

typedef struct {

RTP_header_t rtp_header;
ECA_header_t eca_header;
ECA_payload_t eca_payload[MAX_ECA_SAMPLES]; // MAX_ECA_SAMPLES of 100

}ECA_message_t;             // 1220 bytes

这是中止(核心转储)回溯消息:

*** glibc detected *** ./clientUDPIniDyn: double free or corruption (!prev): 0x081768c8 ***
 ======= Backtrace: =========
 /lib/i386-linux-gnu/libc.so.6(+0x75ee2)[0xb7642ee2]
 ./clientUDPIniDyn[0x804896b]
 /lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0xb75e64d3]
 ./clientUDPIniDyn[0x80486b1]
 ======= Memory map: ========
 08048000-0804a000 r-xp 00000000 08:01 1319522    /home/lin/ULB/Memoire/Client_Server
 /Server/clientUDPIniDyn
 0804a000-0804b000 r--p 00001000 08:01 1319522    /home/lin/ULB/Memoire/Client_Server
 /Server/clientUDPIniDyn
 0804b000-0804c000 rw-p 00002000 08:01 1319522    /home/lin/ULB/Memoire/Client_Server
 /Server/clientUDPIniDyn
 08176000-08197000 rw-p 00000000 00:00 0          [heap]
 b7589000-b75a5000 r-xp 00000000 08:05 264147     /lib/i386-linux-gnu/libgcc_s.so.1
 b75a5000-b75a6000 r--p 0001b000 08:05 264147     /lib/i386-linux-gnu/libgcc_s.so.1
 b75a6000-b75a7000 rw-p 0001c000 08:05 264147     /lib/i386-linux-gnu/libgcc_s.so.1
 b75bf000-b75ca000 r-xp 00000000 08:05 293796     /lib/i386-linux-gnu/libnss_files-
 2.15.so
 b75ca000-b75cb000 r--p 0000a000 08:05 293796     /lib/i386-linux-gnu/libnss_files-
 2.15.so
 b75cb000-b75cc000 rw-p 0000b000 08:05 293796     /lib/i386-linux-gnu/libnss_files-
 2.15.so
 b75cc000-b75cd000 rw-p 00000000 00:00 0 
 b75cd000-b7770000 r-xp 00000000 08:05 293791     /lib/i386-linux-gnu/libc-2.15.so
 b7770000-b7771000 ---p 001a3000 08:05 293791     /lib/i386-linux-gnu/libc-2.15.so
 b7771000-b7773000 r--p 001a3000 08:05 293791     /lib/i386-linux-gnu/libc-2.15.so
 b7773000-b7774000 rw-p 001a5000 08:05 293791     /lib/i386-linux-gnu/libc-2.15.so
 b7774000-b7777000 rw-p 00000000 00:00 0 
 b778d000-b7791000 rw-p 00000000 00:00 0 
 b7791000-b7792000 r-xp 00000000 00:00 0          [vdso]
 b7792000-b77b2000 r-xp 00000000 08:05 293804     /lib/i386-linux-gnu/ld-2.15.so
 b77b2000-b77b3000 r--p 0001f000 08:05 293804     /lib/i386-linux-gnu/ld-2.15.so
 b77b3000-b77b4000 rw-p 00020000 08:05 293804     /lib/i386-linux-gnu/ld-2.15.so
 bfbad000-bfbce000 rw-p 00000000 00:00 0          [stack]
 Aborted (core dumped)
4

2 回答 2

1

这是固定代码,使用 calloc() 不会再出现分段错误

for (rp = result; rp != NULL; rp = rp->ai_next) 
{
     s = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); // socket creation

     ECA_message_t* ECA_paquet;
     ECA_paquet=calloc(NbMesPerFile, sizeof(* ECA_paquet)); // calloc to assign table [NbMesPerFile] length bloc memory for my struct EA_message_t

     // sending m paquets of my struct 
     int m=0;
     for (; m<NbMesPerFile; ++m) 
     {

         Client_update_ECA_data(ECA_paquet,m);  //update the ECA data paquet

         if (sendto(s,ECA_paquet, sizeof(*ECA_paquet) ,0, rp->ai_addr,rp->ai_addrlen)==-1) // send data ECA data pointed by ECA_paquet
         {
             perror("sendto()");
         }
     }

}
于 2013-03-30T07:21:03.267 回答
0
// create socket s
for (rp = result; rp != NULL; rp = rp->ai_next) 
{
        s = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
}

您在这里泄漏文件描述符(套接字)。循环的每次迭代s都会重新分配。并且之前的 s 值丢失了。(我不知道你的链表有多长)

// loop for sending m x struct ECA_message_t 
int m=0;
for (; m<NbMesPerFile; ++m) 
    {

            ECA_message_t* ECA_paquet;
            ECA_paquet=(ECA_message_t*)malloc(sizeof(ECA_message_t)*2400); 
            // 2400 to workaround some not understood memory issue and make sendto() to 
            // work  

            // function initializing ECA_paquet
            Client_update_ECA_data(ECA_paquet,m);
            if (sendto(s, ECA_paquet, sizeof(ECA_paquet)*2400, 0 ,(struct 
                  sockaddr*)&si_other,slen)==-1)
    {
        perror("sendto()");
    }
}

你在这里泄漏内存。循环的每次迭代ECA_paquet都会重新分配。并且 ECA_paquet 之前的值丢失了。永远。(不知道有多大NbMesPerFile

(这可能不是你的段错误的原因,但它至少表明质量不合格)你也不应该转换 malloc()的返回值,(+ #include <stdlib.h>, , 加上检查 malloc() 的返回值。并打开警告编译器的级别。

于 2013-03-28T23:10:13.817 回答