V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
b00tyhunt3r
V2EX  ›  程序员

c 语言套接字编程怪事件

  •  1
     
  •   b00tyhunt3r · 2019-09-25 22:06:06 +08:00 · 2504 次点击
    这是一个创建于 1920 天前的主题,其中的信息可能已经有所发展或是发生改变。
    int main()
    
    {
      struct addrinfo* c;   //创建套接字结构
      char host[1024],serv[1024];
      getaddrinfo("163.com","http",NULL,&c); //取得猪厂 ip 地址及 http 端口号
      int flags = NI_NUMERICSERV; //令服务显示为端口号
      getnameinfo(c->ai_addr,c->ai_addrlen,host,1024,serv,1024,flags);
      printf("host:%s,serv:%s\n",host,serv); //打印 ip 及端口号
      
      freeaddrinfo(c);  //事件起点,释放套接字结构 c                 
      if(!c) 
            printf("c is gone\n");//如果 c 被释放了,打印“c is gone”
      else
     	printf("c is there\n"); //如果 c 没有被释放,打印“c is there”
    	
    }
    

    运行结果: bash-3.2$ ./a.out host:123.58.180.8,serv:80 c is there

    为什么这个结构 c 明明被我 freeaddrinfo 了,还是依然阴魂不散呢?

    16 条回复    2019-09-26 16:54:48 +08:00
    WordTian
        1
    WordTian  
       2019-09-25 22:12:49 +08:00 via Android   ❤️ 1
    你不是专门写 C 的吧,很明显的野指针啊
    ysc3839
        2
    ysc3839  
       2019-09-25 22:42:54 +08:00   ❤️ 1
    因为你只是把 c 的值传给了 freeaddrinfo,freeaddrinfo 没办法修改 c。
    LongMaoz
        3
    LongMaoz  
       2019-09-25 23:26:55 +08:00 via Android   ❤️ 1
    编程没有玄学
    si
        4
    si  
       2019-09-25 23:43:38 +08:00   ❤️ 1
    freeaddrinfo 没有置 0,只是释放,你要主动置 0。
    fengtons
        5
    fengtons  
       2019-09-26 00:04:42 +08:00 via Android   ❤️ 1
    c = NULL;
    opengps
        6
    opengps  
       2019-09-26 00:37:43 +08:00 via Android   ❤️ 1
    猪厂是哪?
    msg7086
        7
    msg7086  
       2019-09-26 00:45:51 +08:00   ❤️ 1
    学一下 C 吧。
    指针指向 0 不代表内存被释放。
    内存被释放不代表指针会指向 0。
    两者是独立事件,所以你代码和注释都是错的。
    b00tyhunt3r
        8
    b00tyhunt3r  
    OP
       2019-09-26 00:51:29 +08:00 via iPad
    谢过各位大佬!
    happy7902
        9
    happy7902  
       2019-09-26 01:14:45 +08:00 via iPhone
    高手,这是高手。
    Mutoo
        10
    Mutoo  
       2019-09-26 07:26:17 +08:00
    getaddrinfo 的参数是 &c
    而 freeaddrinfo 的参数是 c
    前者传的是指针 c 的地址,可以利用此修改该地址的值,即修改 c 本身
    后者则是值传递,传的是指针 c 的内容,顾无法修改 c 本身
    qakito
        11
    qakito  
       2019-09-26 07:51:39 +08:00
    函数形参了解一下
    agostop
        12
    agostop  
       2019-09-26 09:22:13 +08:00
    感觉这像是 java 程序员在写 C
    LeeSeoung
        13
    LeeSeoung  
       2019-09-26 09:53:00 +08:00
    java 也不是这么写的 楼上别引战。。
    catcn
        14
    catcn  
       2019-09-26 10:15:12 +08:00
    freeaddrinfo 传入的指针类型,是值传递,肯定不会修改或者设置为 NULL 啦。。
    dosmlp
        15
    dosmlp  
       2019-09-26 15:36:17 +08:00 via Android
    楼主去学学 c 语言基础吧
    xdtr
        16
    xdtr  
       2019-09-26 16:54:48 +08:00   ❤️ 1
    getaddrinfo 后 c 指向一个 addrinfo 结构链表。“The getaddrinfo() function allocates and initializes a linked list of addrinfo structures, one for each network address that matches node and service, subject to any restrictions imposed by hints, and returns a pointer to the start of the list in res. The items in the linked list are linked by the ai_next field.”
    由于调用 getaddrinfo 后动态分配内存,必须通过调用 freeaddrinfo 释放内存。“The freeaddrinfo() function frees the memory that was allocated for the dynamically allocated linked list res”。
    这就很清楚了,freeaddrinfo 并不会释放 c,所以 c 必须手动释放。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2765 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 12:59 · PVG 20:59 · LAX 04:59 · JFK 07:59
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.