zoukankan      html  css  js  c++  java
  • C语言指针的那些坑

    那些年把我们坑惨的指针

    一、引言

      当我们使用c语言的时候,不可避免的就得用到指针,然后对于刚刚接触C语言的猿兄们,可能会有点不适应,特别是刚刚从python等离硬件很远的语言转过来的。

    下面我为大家总结下常见的几个坑。

    二、用事实说话

      

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #define MAXLEN 100
     4 typedef struct
     5 {
     6     char* data;
     7     int len;
     8 }Node;
     9 
    10 void create(Node* head){
    11     Node* node = (Node*)malloc(sizeof(Node));
    12     node->data = (char*)malloc(MAXLEN*sizeof(char));
    13     head = node;
    14 }
    15 void destroy(Node* head){
    16     free(head->data);
    17     head->data = NULL;
    18     free(head);
    19 }
    20 int main(int argc, char const *argv[])
    21 {
    22     Node* p = NULL;
    23     create(p);
    24     printf("%p
    ", p);
    25     destroy(p);
    26     return 0;
    27 }

    哇!通过上面的代码,我们看到我们可以很容易的通过create创建一个Node结点,下面我们就来理性分析一波。

    首先,malloc在堆空间申请空间,create运行结束后,堆空间内存也不会释放,对吧?很有道理,然后我们再把开辟的空间的地址给head返回

    正如我们知道的我们传进去的是指针(是一个地址)按理来说返回的应该是新申请的堆空间地址。

    然而,并不是,我们看看结果:

    返回的是一个NULL,再destroy一次(free了NULL)

    就出现 seg fault.

    惊不惊喜,意不意外!!!黑人问号.jpg

    那问题在哪里??? why??? why???

    下面我们来看看问题出在哪里。

    三、问题分析

      在c语言中,我们将char*,int*等带有*的类型称为指针类型,指针类型同int,char,float,double一样都是基本数据类型。

    int保存的32位整型。.eg. int sum = 10。sum实际上是一个内存地址,这个内存地址的值就是10。而指针类型int* p = &sum

    p实际上也是个内存地址,而其值就是&sum(sum的内存地址)。

    在分析之前我们先来认识几个符号:

    *:取值符号,取对应内存的值,此外也是指针的标识符

    ->:取值符号,取对应内存的值

    &:取地址符号,取变量名对应的地址

    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    在我们的问题中我们将一个Node 类型指针传入create,实际就是将实参 Node* p,复制给形参Node* head.

    这里复制的是"p"也就是指针保存的地址。head这个指针现在保存的地址就是p指向的地址了。

    然后我们malloc一快堆区空间,返回一个堆区内存地址给head,也就是说:

    之前head指针保存的地址是实参p的地址,而现在head指向的地址是,堆区内存的地址。

    哈哈,原来问题就出在这里。我们以为传就去p的地址,然后可以通过12-13这两个语句,让p保存

    堆区内存地址,然后并不是这样。那我们可以怎样解决了?

    很容易*这个符号就是取内存对应的值,也就是说我们只要*head这样就是指向p指向内存的值,我们再

    把malloc申请的地址的值给*head,这样就成功解决了。话不多说上code

    #include <stdio.h>
    #include <stdlib.h>
    #define MAXLEN 100
    typedef struct 
    {
        char* data;
        int len;
    }Node;
    
    void create(Node* head){
        Node* node = (Node*)malloc(sizeof(Node));
        node->data = (char*)malloc(MAXLEN*sizeof(char));
        *head = *node;
        free(node);
    }
    void destroy(Node* head){
        free(head->data);
        head->data = NULL;
        free(head);
    }
    int main(int argc, char const *argv[])
    {
        Node* p = (Node*)malloc(sizeof(Node));
        create(p);
        printf("%p
    ", p);
        destroy(p);
        return 0;
    }

    此外还可以直接返回malloc申请到的地址。

    转载请注明出处:https://www.cnlogs.com/jake9402

  • 相关阅读:
    ORACLE 查找数据库中有记录的表
    [原]Asp.Net 错误:无法连接到Asp.Net Developement server
    中国移动手机话费查询号码1008611
    动手修改VS2008的解决方案文件,以让VS2005打开它
    [转]飞秋使用说明与常见问题解决方法
    微软发布Fix it 修复Windows 7等系统0day漏洞
    Oracle DECODE 函数应用示例
    [转]C#实现访问网络共享文件夹
    c#保留小数点后位数的方法
    [转]微软紧急修复高危漏洞 30万网民PC已遭攻击
  • 原文地址:https://www.cnblogs.com/jake9402/p/7712180.html
Copyright © 2011-2022 走看看