您好,欢迎来到五一七教育网。
搜索
您的当前位置:首页C语言二重指针与malloc

C语言二重指针与malloc

来源:五一七教育网

(内容主要源于网上,只是加入了些自己的剖析)

假设有一个二重指针:

char **p;

同时有一个指针数组

char *name[4];

如何引用p呢? 首先我们有程序代码如下 

#include <stdio.h> 
int main() { 
    char *s = "I love you"; 
    char *s1 = "you love me"; 
    char *s2 = "she love you"; 
    char *s3 = "he love her"; 
    char *name[4]; 
    name[0] = s; 
    name[1] = s1; 
    name[2] = s2; 
    name[3] = s3; 

    char **p; 
    p = name + 2; 
    printf("%d\n", *p); 
    printf("%d\n", **p); 
    printf("%c\n", **p); //为什么这个打印s
    printf("%d\n", p); 
    printf("%d\n", *&p); 
    printf("%d\n", &p); 
    printf("%s\n", *p);  //而这个打印出了字符串
    return 0; 
}

 输出结果依次为:

4333636

115

s

1244976

1244976

12449

she love you

分析:

3、 我们在分析用%d来打印*p, 为何得到了4333636。 理由是:p是二重指针,所以*p表示还是一个一重指针变量,它的具体表示可以是*(p + 0)。 为了便于理解,我们这样假设有一个 char *row; row = *(p + 0);这样我们就把问题转化 成了一维的指针了,我们打印*p,其实就是打印row,这样我们可以参考分析(1)。

6、 分析%c 为何能打印's'。分析(5)已经全说了。

 

相关面试题

错误的例程:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void Getmemery(char *p)
{
    p=(char *)malloc(100);
  //下面一行是自己加的
  *p=1; //为了对比问题出在哪里 } void main() { char *str=NULL; Getmemery(str); strcpy(str,"hello world"); printf("%s",str); free(str); }

编译时通过,运行时会输出段错误。

其实还是C里面经典的错误(值传递swap问题),为什么第一眼看上去是对的,因为我们一贯地认为指针传递就可以这么操作,然后忽略了后面的修改是否有效。

若想要其有效只能,用指针的方式传入str(其实指针变量也是某一块内存的内容)[&str]并对指针操作(下面第2种修改方法),或者将修改后的指针变量返回(下面第1种方法)。

一种修正方法:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *Getmemery(void)  //通过返回指针变量
{
    char *p=(char *)malloc(100);
    return p;
}

void main()
{
    char *str=NULL;

    str = Getmemery();
    strcpy(str,"hello world");
    printf("%s",str);
    free(str);
}

另一种修改方法

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void Getmemery(void **p)  //通过使用二重指针
{
    *p=(void *)malloc(100);
}

void main()
{
    char *str=NULL;

    Getmemery(&str);
    strcpy(str,"hello world");
    printf("%s",str);
    free(str);
}

分析一下之前的程序为什么会错了。

(1)void Getmemery(char *p)

(2)char *str=NULL;

(3)Getmemery(str);

1中子程序的形参是一个指针,然后很自然会想到2,3中的调用方式,本来的想法是用malloc分配内存,然后修改传入的指针变量,那么最后就根据通过 strcpy(str,"hello world"); 就可以向分配的内存里面写数据了。一切都是那样流畅,对,因为这个用法平时用习惯了,所以根本不会去考虑正确性。

void Getmemery(void **p)
{
 *p=(void **)malloc(100);
}

子程序修改为这个样子,出入的参数也得修改

char *str=NULL;
Getmemery(&str);

那么可以这样理解,因为形参是2重指针,所以 p 对应 &str ,*P 对应 str,之前说了,我们的目的是要修改 str的值,所以很自然,我们用 *p = xxx 这样的形式去修改了。

这样得到的程序就正确了。

 

malloc

标准3部曲:malloc + free +指针置空

malloc申请的是堆(heap)空间

malloc使用注意事项:

2、malloc分配完之前注意初始化,以及防止越界操作。

3、free之后注意将指针置为NULL.

/*
date:20100824
description:malloc使用规范探讨
in参数:申请的堆内存字节数,注意int,short,float需要自己乘上相应字节数。
out返回值:void *
*/
main()
{
char *str=NULL;
str=(char *)malloc(10);   //注意malloc返回值是void *,申请时需要强制转换成需要的类型
memset(str,0,10);       //如果不清空,申请的区域值是随机的,养成好习惯
strcpy(str,"happylife");   //使用strcpy特别注意拷贝的字符串长度<=10-1,即要预留字符串结束标志'\0'
puts(str);
free(str);
printf("str[address]:%s[%x]\n",str,str);  //这里的str内容为空,但是指针地址还在

str=NULL;            //注意指针free之后该指针仍然存在,最好将它指向为空。
printf("str[address]:%s[%x]\n",str,str);  //这里的str内容为空,地址也为空
}

  

转载于:https://www.cnblogs.com/kwseeker-bolgs/p/4588162.html

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- 517ttc.cn 版权所有 赣ICP备2024042791号-8

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务