zoukankan      html  css  js  c++  java
  • C语言中关于字符数组与字符指针的本质区别

    字符指针和字符数组有一个小的区别:

    字符指针是一个指针变量,他是要占用空间的,这个空间的大小取决于机器是多少位的64位的就要占用8个字节,因为他是地址,64位系统的地址是用64位来表示的

    字符数组虽然在使用上类似上像是在使用字符指针,然而实际上,本质上他只不过是编译器在内存中做的标记,字符数组本身不占用任何空间。

    所以,下面的struct在64位机器上的大小是16个字节。

    struct test{
        int32_t a;
        
    char* buff;
        
    char buf[];
    }; 
    int32_t a; 应当使用4个字节,但是64位机器要做64位对其,所以占用了8个字节

    char* buff; buff是一个指针,又占用一个64为的地址空间,再加8个字节

    char buf[]; 这个东西一个空间也不占用,他就像是一个隐形的字符指针

    这一点在redis的

    Simple Dynamic Strings中得到了出色的应用,参考:http://redis.io/topics/internals-sds

    修改了的代码可以看到效果: 

    #include <stdio.h>
    #include 
    <iostream>

    using namespace std;

    typedef 
    char *sds;
    struct sdshdr {
        
    long len;
        
    long free;
        
    char buf[];
    };

    sds sdsnewlen(
    const void *init, size_t initlen) {
        
    struct sdshdr *sh;

        sh 
    = (sdshdr*)malloc(sizeof(struct sdshdr)+initlen+1);
        
    if (sh == NULL) return NULL;
        sh
    ->len = initlen;
        sh
    ->free = 0;
        
    if (initlen) {
            
    if (init) memcpy(sh->buf, init, initlen);
            
    else memset(sh->buf,0,initlen);
        }   
        sh
    ->buf[initlen] = '\0';

        printf(
    "addr of len : 0x%X\n",&sh->len);
        printf(
    "addr of free: 0x%X\n",&sh->free);
        printf(
    "addr of buf : 0x%X\n",&sh->buf);
        printf(
    "addr of sh  : 0x%X\n",sh);
        
    return (char*)sh->buf;
    }
    size_t sdslen(
    const sds s) {
        printf(
    "addr of s   : 0x%X\n",s);
        
    struct sdshdr *sh = (sdshdr*) (s-(sizeof(struct sdshdr)));
        printf(
    "addr of sh  : 0x%X\n",sh);
        
    return sh->len;
    }
    main()
    {
        sds str 
    = sdsnewlen("redis"5);
        cout
    <<"-----------------------"<<endl;
        cout
    <<(sdslen(str))<<endl;;
    }

    以上代码的输出是: 

    addr of len : 0xE8D3010
    addr of free: 
    0xE8D3018
    addr of buf : 
    0xE8D3020
    addr of sh  : 
    0xE8D3010
    -----------------------
    addr of s   : 
    0xE8D3020
    addr of sh  : 
    0xE8D3010
    5

    在这个sdshdr中,buf就好像是一个隐藏的指针,他不参与大小的运算(其实根本没有给他分配内存空间),但是却保存着sds最重要的数据内容。

    相关的描述也可以在下面的文章中看到:

    http://www.cnblogs.com/welkinwalker/archive/2011/01/05/1926203.html 


  • 相关阅读:
    solr中facet、group查询
    Solr开发文档
    Java的Properties类和读取.properties文件
    CentOS RPM安装MySQL-5.6
    C#中的 IList, ICollection ,IEnumerable 和 IEnumerator
    Linq to Xml
    Linq查询
    XDocument和XmlDocument的区别
    关于扩展方法
    今天刚刚开通了园子
  • 原文地址:https://www.cnblogs.com/welkinwalker/p/2168571.html
Copyright © 2011-2022 走看看