• 函数调用


    函数调用可能引发的问题

    1.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    void getmemory(char *p, int num)
    {
        p = (char *)malloc(num);
    }
    
    int main()
    {
        char *str = NULL;
        getmemory(str, 100);
        strcpy(str, "hello");
        printf("%s
    ", str);
        return 0;
    }

    传入getMemory(char *p, int num)函数的形参为字符串指针,在函数内部修改形参并不能真正的改变传入形参的值,执行完 

    char *str = NULL;
    GetMemory( str );

    后的str仍然为NULL;

    毛病出在函数GetMemory 中。

    编译器总是要为函数的每个参数制作临时副本,指针参数p的副本是 _p,编译器使 _p = p。

    如果函数体内的程序修改了_p的内容,就导致参数p的内容作相应的修改。

    这就是指针可以用作输出参数的原因。

    在本例中,_p申请了新的内存,只是把 _p所指的内存地址改变了,但是p丝毫未变。

    所以函数GetMemory并不能输出任何东西。事实上,每执行一次GetMemory就会泄露一块内存,因为没有用free释放内存。

    程序会在

    strcpy(str,"hello");

    这段代码运行错误。

    2.malloc后没有判断非空

    3.最好使用strncpy,控制copy的个数

    4.申请内存没有释放

    函数最后可以修改为:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    void getmemory(char **p, int num)
    {
        *p = (char *)malloc(num);
    }
    
    int main()
    {
        char *str = NULL;
        getmemory(&str, 100);
        strcpy(str, "hello");
        printf("%s
    ", str);
        return 0;
    }

    1.能够输出hello

    2.Test函数中也未对malloc的内存进行释放。 

    3. GetMemory避免了1的问题,传入GetMemory的参数为字符串指针的指针,但是在GetMemory中执行申请内存及赋值语句 

    *p = (char *) malloc( num );

    后未判断内存是否申请成功,应加上: 
    if ( *p == NULL )
    {
       ...//进行申请内存失败处理 
    }
    &str是指针的地址,将指针的地址传给形参p,则p也指向str,

    所以*p = (char *)malloc(sizeof(char) * num);也就是给p所指向的str分配了内存,所以正确。

    2.

    char *getMemory( void )
    {
        char p[] = "hello world";
        return p;
    }
    int main( void )
    {
        char *str = NULL;
        str = getMemory();
        printf( str );
        return 0;  
    }

    可能是乱码。             

     char p[] = "hello";      
     return p;  
    p[]数组为函数内的局部自动变量,在函数返回后,内存已经被释放。

    3.

    int main(void)
    {
        char *str = (char *) malloc(100);
        strcpy(str, “hello”);
        free(str);      
        if(str != NULL)
        {
          strcpy(str, “world”);
          printf(str); 
         }
         return 0;
    }


    char *str = (char *) malloc(100);
    后未进行内存是否申请成功的判断;

    另外,在free(str)后未置str为空,导致可能变成一个“野”指针,应加上: 
    str = NULL;

    4.

    char *getString(void)
    {
        char *p = "hello world";
        return p;
    }
    
    int main(void)
    {
        char *str = NULL;
        str = getString();
        cout<< str << endl;
        return 0;
    }

    函数运行虽然不会出错,但是函数GetString的设计概念却是错误的。

    因为GetString内的“hello world”是常量字符串,位于静态存储区,它在程序生命期内恒定不变。

    无论什么时候调用GetString,它返回的始终是同一个“只读”的内存块。

    5.

    void test(void)
    {
        char *p = (char *) malloc(100);
        strcpy(p, “hello”);
        free(p);        // p 所指的内存被释放,但是p所指的地址仍然不变
    if(p != NULL)   // 没有起到防错作用
        {
           strcpy(p, “world”);  // 出错
        }
    }


    6.

    char *getMemory(void)
    { 
         return "hello world";
    }
    int main(void)
    {
        char *str = NULL;
        str = GetMemory3(); 
        printf(str);
        return 0;
    }

    正确打印hello world, 字符串在常量区

    7.

    char *GetMemory(int num)
    {
        char *p = (char *)malloc(sizeof(char) * num);
        return p;
    }
     
    int main(void)
    {
        char *str = NULL;
        str = GetMemory3(100); 
        strcpy(str, "hello");
        cout<< str << endl;
        free(str); 
        return 0;  
    }

    正确打印hello world

    8.

    void swap( int* p1,int* p2 )
    {
        int *p;
        *p = *p1;
        *p1 = *p2;
        *p2 = *p;
    }
    //在swap函数中,p是一个“野”指针,有可能指向系统区,导致程序运行的崩溃。
    //应该改为
    void swap( int* p1,int* p2 )
    {
        int p;
        p = *p1;
        *p1 = *p2;
        *p2 = p;
    }

    参考:

    https://blog.csdn.net/yangtrees/article/details/8923350

    https://blog.csdn.net/u012199908/article/details/78607432?utm_source=blogxgwz1

  • 相关阅读:
    Fragment 总结
    Varnish缓存服务器的搭建配置手册
    关于页面缓存服务器的研究报告
    基于Html5的移动端开发框架的研究
    C#的Process类的一些用法
    c#中进程的使用
    C#反射(转载)
    进制的转换 以及十进制转换成x进制的代码
    算法及其复杂度
    cocos总结
  • 原文地址:https://www.cnblogs.com/zzdbullet/p/10669013.html
Copyright © 2020-2023  润新知