有关二级指针的一些疑问和猜想

作者:超级管理员 更新时间:2017-09-12 07:57:00 来源:未知 点击:15642
先上代码:#include #include int main() {    char **p;    char *c,*b;    unsigned int i
先上代码:
#include <stdio.h>
#include <stdlib.h>

int main() {
    char **p;
    char *c,*b;
    unsigned int i = 0;
    
    p = ( char ** )malloc( 5 * sizeof ( char *) );
    c = ( char * )malloc( sizeof( char *) );
    b = ( char * )malloc( sizeof( char *) );
    *c = 'a';
    *b = 'b';

    *p = c;
    *(p+1) = b;

     printf( "%d,%d,%d\n", c, b, *p );
     printf( "%c\n", p[1][0] );
     free( c );
     free( b );
     return 0;
}


在代码中先是给二级指针分配了内存空间 但是二级指针中的元素却是另外定义的一些指针 打印了一下各个指针的地址发现已经是不连续的了 那按数组的访问方式却是可以准确访问到 那么一开始给二级指针分配的空间是否已经无效了 假如指针c和指针b的地址相差很大 那么是不是二级指针p的内存空间就是从c到b的地址那么大?具体的内存空间分配到底是什么呢?指针按数组的方式访问元素的实质又是什么呢?求大神解疑

p、b、c分别指向了3块内存,

p是一个地址数组,它本身指向的内存块肯定是连续的5个指针大小的内存,但是它的各元素值可能是离散的,p[0]与c一样指向了第2 次申请的堆内存,p[1]跟b一样指向了第3次申请的堆内存。

32位程序,一个指针大小也就4字节,p指向的堆内存就是20字节,p[0]跟p[1]肯定是连续的,就相差4字节。



首先,你打印p的地址有问题
printf( "%p,%p\n", p, p+1 );这个才是p的地址,b和c的地址只是赋值给 *p 和 *(p+1) 

举一个简明的例子。
有五个并排的格子,编号即为p+0, p+1, p+2...
有两个不知道什么东西的东西b和c,只知道它们所处的位置

此刻在前格子里面记录它们所在的地址
*p = c;
*(p+1) = b;

地址是变量在内存中的位置(格子所在的地址),指向的内存其实就是记录在这个内存中的一个值(格子内所记录的地址)

仅供参考:
//在堆中开辟一个3×4×5的3维int数组
#include <stdio.h>
#include <malloc.h>
int ***p;
int i,j,k;
void main() {
    p=(int ***)malloc(3*sizeof(int **));
    if (NULL==p) return;
    for (i=0;i<3;i++) {
        p[i]=(int **)malloc(4*sizeof(int *));
        if (NULL==p[i]) return;
        for (j=0;j<4;j++) {
            p[i][j]=(int *)malloc(5*sizeof(int));
            if (NULL==p[i][j]) return;
        }
    }
    for (i=0;i<3;i++) {
        for (j=0;j<4;j++) {
            for (k=0;k<5;k++) {
                p[i][j][k]=i*20+j*5+k;
            }
        }
    }
    for (i=0;i<3;i++) {
        for (j=0;j<4;j++) {
            for (k=0;k<5;k++) {
                printf(" %2d",p[i][j][k]);
            }
            printf("\n");
        }
        printf("---------------\n");
    }
    for (i=0;i<3;i++) {
        for (j=0;j<4;j++) {
            free(p[i][j]);
        }
        free(p[i]);
    }
    free(p);
}
//  0  1  2  3  4
//  5  6  7  8  9
// 10 11 12 13 14
// 15 16 17 18 19
//---------------
// 20 21 22 23 24
// 25 26 27 28 29
// 30 31 32 33 34
// 35 36 37 38 39
//---------------
// 40 41 42 43 44
// 45 46 47 48 49
// 50 51 52 53 54
// 55 56 57 58 59
//---------------

//在堆中开辟一个2×3×4×5的4维int数组
#include <stdio.h>
#include <malloc.h>
int ****p;
int h,i,j,k;
void main() {
    p=(int ****)malloc(2*sizeof(int ***));
    if (NULL==p) return;
    for (h=0;h<2;h++) {
        p[h]=(int ***)malloc(3*sizeof(int **));
        if (NULL==p[h]) return;
        for (i=0;i<3;i++) {
            p[h][i]=(int **)malloc(4*sizeof(int *));
            if (NULL==p[h][i]) return;
            for (j=0;j<4;j++) {
                p[h][i][j]=(int *)malloc(5*sizeof(int));
                if (NULL==p[h][i][j]) return;
            }
        }
    }
    for (h=0;h<2;h++) {
        for (i=0;i<3;i++) {
            for (j=0;j<4;j++) {
                for (k=0;k<5;k++) {
                    p[h][i][j][k]=h*60+i*20+j*5+k;
                }
            }
        }
    }
    for (h=0;h<2;h++) {
        for (i=0;i<3;i++) {
            for (j=0;j<4;j++) {
                for (k=0;k<5;k++) {
                    printf(" %3d",p[h][i][j][k]);
                }
                printf("\n");
            }
            printf("--------------------\n");
        }
        printf("=======================\n");
    }
    for (h=0;h<2;h++) {
        for (i=0;i<3;i++) {
            for (j=0;j<4;j++) {
                free(p[h][i][j]);
            }
            free(p[h][i]);
        }
        free(p[h]);
    }
    free(p);
}
//   0   1   2   3   4
//   5   6   7   8   9
//  10  11  12  13  14
//  15  16  17  18  19
//--------------------
//  20  21  22  23  24
//  25  26  27  28  29
//  30  31  32  33  34
//  35  36  37  38  39
//--------------------
//  40  41  42  43  44
//  45  46  47  48  49
//  50  51  52  53  54
//  55  56  57  58  59
//--------------------
//=======================
//  60  61  62  63  64
//  65  66  67  68  69
//  70  71  72  73  74
//  75  76  77  78  79
//--------------------
//  80  81  82  83  84
//  85  86  87  88  89
//  90  91  92  93  94
//  95  96  97  98  99
//--------------------
// 100 101 102 103 104
// 105 106 107 108 109
// 110 111 112 113 114
// 115 116 117 118 119
//--------------------
//=======================
//

http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素
http://edu.csdn.net/course/detail/2455 C语言指针与汇编内存地址-二.函数
http://edu.csdn.net/course/detail/2516 C语言指针与汇编内存地址-三.数组和二维数组
http://edu.csdn.net/course/detail/2517 C语言指针与汇编内存地址-四.三维数组

谢谢各位大神的回答,是我表达不清楚 我想问得是在一维数组中地址是连续的 那么二维数组呢? 上述的二级指针如果我们是当作一个二维数组看待 指针c和指针b记录的是一个字符 但同时可以看作是一个二维数组中的第一维数组 那么它们的地址是连续的没错 那么二维数组的内存空间是否连续的?二级指针的地址是否跟二维数组一样是连续的?如果不连续 那么给二级指针分配的内存空间又是指什么?

引用 4 楼 zhao4zhong1 的回复:
http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素
http://edu.csdn.net/course/detail/2455 C语言指针与汇编内存地址-二.函数
http://edu.csdn.net/course/detail/2516 C语言指针与汇编内存地址-三.数组和二维数组
http://edu.csdn.net/course/detail/2517 C语言指针与汇编内存地址-四.三维数组
谢谢 我去认真学习一下

引用 1 楼 sdghchj 的回复:
p、b、c分别指向了3块内存,

p是一个地址数组,它本身指向的内存块肯定是连续的5个指针大小的内存,但是它的各元素值可能是离散的,p[0]与c一样指向了第2 次申请的堆内存,p[1]跟b一样指向了第3次申请的堆内存。

32位程序,一个指针大小也就4字节,p指向的堆内存就是20字节,p[0]跟p[1]肯定是连续的,就相差4字节。
也就是说二级指针p的内存空间只是用来存储元素中的地址 而不是b和c的值 因此分配的空间不用范围大到包括指针b和指针c的地址?

推荐阅读

热门内容

求助一个计算问题?

#include in...

请解惑,关于QT用C++写串口通信时的一

我把代码贴出来吧,请帮我看看是哪里出了问...

已添加头文件,但报错找不到标识符

引用错误1error C3861: “r...

错误2365,怎么解决啊,求助

如图这么多短变量名放一块儿,很容易重名的...

感觉现代c++不如d语言

功能都是那些功能,现代c++的实现语法太...

逐行读取文件+并发处理,和先读入整个文件

文本的每一行都是一条记录,程序要求对每条...

C语言新手求助,输出的数字非常大

本帖最后由z4164362于2017-0...

c小白 求帮帮忙

# include #...

求助,对使用什么软件比较迷茫

我现在使用VS2017在对一个曲柄滑块机...

关于c语言图形界面的光条式菜单问题

本帖最后由qq_40091933于201...

最新内容

int c那一行报错

#includeusing namespace std;cl...

有关二级指针的一些疑问和猜想

先上代码:#include #include 

做好网站下面三点让收录效果更好

  第一、网站标题要合适。    现在的社会酒香都怕巷子深,更何况没有气味的优质...

大神是怎样读书的

while(getline(cin,line))带着问题读。while(getl...

求助一个计算问题?

#include int main(void){long do...

android canvas怎么清除一张画上的图而不影响背景图(新手问个低级问题莫吐槽)

protected void onDraw(Canvas canvas) {su...

美图T8s上手:女同事抢着要帮我测拍照

        2017年9月7日,美图公司在北京798举办发布会,正式发布了新...

四曲面双摄旗舰 不等iPhone X今天就买它

  中关村在线消息:作为国产曲面屏旗舰的代表,vivo Xplay6采用新一代5...

前置双摄新星旗舰 360 N5S天猫送8重礼

    中关村在线消息:360 N5S是360公司在2017年5月23日发布的手...

果8来了也不怕 京东买努比亚Z17畅享版

    iPhone 8即将发布,而对于智能手机市场来说,无疑来了一位非常强劲的...

不惧iPhone8来袭 京东热门手机TOP10

    眼看iPhone 8就要发布了,很多用户的目光投向了其将为我们带来的黑科...

黄牛酒后真言 iPhone 8不加2000绝不卖

    明天天凌晨全新iPhone(下文暂称iPhone 8)就要发布了,听说是...

别忽略离你最近的相机 vivo X9s在京东

  主打自拍的手机越来越多,因此很多用户在挑选自拍功能较好的手机时,多多少少都有...

从千元到旗舰 你想要的颜值手机都在这

  现在买手机很流行讲究性价比,但是这个东西不同的消费区间所认定的标准不同,很难...

数说新机:荣耀V9 play颜值与性价比齐飞

    2017年9月6日,荣耀在广州举办“青春加速度”新品发布会,发布荣耀V9...

三星Note8&iPhone8今夜王见王 你选谁?

    三星盖乐世Note 8国行版将于9月13日在北京发布,而就在同一天凌晨,...

这几款Android手机每个都堪比iPhone 8

    每当新款iPhone发布,热点新闻就层出不穷,今年同样几乎所有的科技媒体...

苹果iPhone 6S(全网通)北京2797元

    【中关村在线北京行情】苹果iPhone6S(全网通)手机,近日在商家“金...

苹果iPhone 7 Plus全网通 北京4960元

    【中关村在线北京行情】苹果iPhone7Plus(全网通)手机,近日在商...

为蹭“全面屏”的热点 各厂商套路不一

     2017年手机争霸赛已经进入到下半场环节,尽管不是明面上的PK赛制,但...