问题描述:

 #include <stdio.h>

 int main(void)
{
//program 6.3 Arrays of strings
char str2[][]; for(int i=;i<;++i){
for(int j = ;j<;j++){
str2[i][j]='a';
//printf("%p ", &str2[i][j]);
}
//printf("\n");
} for(int i=;i<;++i){
for(int j = ;j<;j++){     // 索引 j->12 printf("%c",str2[i][j] );  
//printf("%p ",&str2[i][j]);
}
printf("\n");
}
return ;
}

运行结果:

aaaaaaaaaaaa
aaaaaaaaaaaa
aaaaaaaaaaNULNUL

显然代码第18行数组索引越界(java:IndexOutOfBoundsException),但程序编译运行通过,且越界索引对应的数组值补为a和NULL。


                                                    
如上图所示, &numbers[][] = &number[][] + sizeof(number) / strnlen_s( number, sizeof(str));
即number[1][0]的地址等于number[0][4]的地址加上数组number的类型所占字节数(如int占4字节)。

通过打印数组每个元素地址观察得出原因

 #include <stdio.h>

 int main(void)
{
//program 6.3 Arrays of strings
char str2[][]; for(int i=;i<;++i){
for(int j = ;j<;j++){
str2[i][j]='a';
}
} for(int i=;i<;++i){
for(int j = ;j<;j++){
printf("%c",str2[i][j] );
printf("%p ",&str2[i][j]);
}
printf("\n");
}
return ;
}

运行结果:

a0x7ffee509c710  a0x7ffee509c711  a0x7ffee509c712  a0x7ffee509c713  a0x7ffee509c714  a0x7ffee509c715  a0x7ffee509c716  a0x7ffee509c717  a0x7ffee509c718  a0x7ffee509c719  a0x7ffee509c71a  a0x7ffee509c71b
a0x7ffee509c71a a0x7ffee509c71b a0x7ffee509c71c a0x7ffee509c71d a0x7ffee509c71e a0x7ffee509c71f a0x7ffee509c720 a0x7ffee509c721 a0x7ffee509c722 a0x7ffee509c723 a0x7ffee509c7 a0x7ffee509c7
a0x7ffee509c7 a0x7ffee509c7 a0x7ffee509c726 a0x7ffee509c727 a0x7ffee509c728 a0x7ffee509c729 a0x7ffee509c72a a0x7ffee509c72b a0x7ffee509c72c a0x7ffee509c72d NUL0x7ffee509c72e NUL0x7ffee509c72f

注意标注的两组彩色地址,想象中出现越界的str2[0][10]、str2[0][11]与str2[1][0]、str2[1][1]地址是一致的,故越界索引的数组值为a。即str2[0][10]==str2[1][0],str2[0][11]==str2[1][1]。


延伸

     char str1[][] = {"AAAAAAAAAA","BBBBBBBBB","CCCCCCCCCC","DDDDDDDDD"};   //10个A
char str2[][] = {"AAAAAAAAAA","BBBBBBBBB","CCCCCCCCC","SSS"};      //9个A

编译报错     str1:initializer-string for array of chars is too long

C中的字符串总是由\0字符结束,所以字符串的长度永远比字符串中的字符数多1.

   unsigned int count = ;
  while (str1[count])
  ++count;

'\0'字符的ASCII码是0,对应于布尔值false。其他ASCII码都不是0,对应布尔值true。因此,只要str1[count]不是'\0',循环就继续执行。

 #include <stdio.h>

 int main()
{ //program 6.3 Arrays of strings
//char str[][10] = {"AAAAAAAAAA","BBBBBBBBB","CCCCCCCCC","DDDDDDDDD"};
//char str2[][10] = {"AAAAAAA","BBBBBBBB","CCCCCCCC","SSS"};
char str2[][]; for(int i=;i<;++i){
for(int j = ;j<;j++){
str2[i][j]='a';
//printf("%p ", &str2[i][j]);
}
//printf("\n");
} for(int i=;i<;++i){
for(int j = ;j<;j++){
printf("%c",str2[i][j] );
//printf("%p ",&str2[i][j]);
}
printf("\n");
} return ;
}

输出结果:

1. aaaaaaaaaa
2. aaaaaaaaaa
3. aaaaaaaaaa

本文一开始使用测试程序使用for循环对数组对应索引进行赋值则没有使用'\0'做为结束标志,三个字符串间没有分隔标志,可以说它们并不是字符串而是单一的字符。


由于本人刚入门,文中不免有这样或者那样的错误,希望各位朋友们不吝赐教指正。

最后由于考研时间原因,列出此程序小弟还有的一处疑惑

 #include <stdio.h>

 int main()
{
char str2[][]; for(int i=;i<;++i){
for(int j = ;j<;j++){
str2[i][j]='a';
}
} for(int i=;i<;++i){
for(int j = ;j<;j++){
printf("%c",str2[i][j] );
//printf("%p ",&str2[i][j]);
}
printf("\n");
}
return ;
}

运行结果:

aaaaaaaaaaaaaaa
aaaaaaaaaaaaaaa
aaaaaaaaaaNULNUL`QR

红色标记的字符经多次编译发现其字符会变动

再次编译结果:

aaaaaaaaaaaaaaa
aaaaaaaaaaaaaaa
aaaaaaaaaaNULNULDLEȜ

C/C++ char数组存储字符串内存地址的更多相关文章

  1. 结构体地址 字符串地址 数组地址 辨析 字符char是整型 内存地址

    小结: 1.函数传参中,结构体不同数组,结构体是传值,指针和数组是传地址:2.随声明顺序,指针变量的内存地址从低到高,其他从高到低:3.char c[]字符数组,即数组的一种:char *c字符指针, ...

  2. C语言基础:指针类型与指针和数组、字符串的关系

    //指针变量就是用来存储地址的,只能存储地址 格式:  int  *p;  这个p为指针变量:指针变量占8个字节 类型是用来说明这个指针指向的类型: 比如上边的int代表这个指针变量会指向int类型的 ...

  3. Delphi中的各种字符串、String、PChar、Char数组

    参考博客:http://www.cnblogs.com/pchmonster/archive/2011/12/14/2287686.html 其中的所有代码均在Delphi7下测试通过. Delphi ...

  4. 【漏洞分析】两个例子-数组溢出修改返回函数与strcpy覆盖周边内存地址

    修改返回函数 return 0 下面的程序的运行流程为main()函数调用了Magic()函数,通常执行完Magic()函数后会调用return 0 的地址, 但是在执行Magic()函数中时,数组下 ...

  5. 字符串(一):char 数组

    字符串使用方法整理 系列: 字符串(一):char 数组 字符串(二):string 1. 声明 如下是一个例子(=> 表示表达式等价): char a[20] = "abcd&quo ...

  6. 为什么 char 数组比 String 更适合存储密码?

    推荐阅读:5 个刁钻的 String 面试题! 另一个基于 String 的棘手 Java 问题,相信我只有很少的 Java 程序员可以正确回答这个问题. 这是一个真正艰难的核心 Java 面试问题, ...

  7. 为什么 char 数组比 Java 中的 String 更适合存储密码?

    另一个基于 String 的棘手 Java 问题,相信我只有很少的 Java 程序员可以正确回答这个问题.这是一个真正艰难的核心Java面试问题,并且需要对 String 的扎实知识才能回答这个问题. ...

  8. 存储opline的内存地址可以实时跟踪opcode的执行

    static intphp_handler(request_rec *r) { /* Initiliaze the context */ php_struct * volatile ctx; void ...

  9. 软件素材---linux C语言:拼接字符串函数 strcat的用例(与char数组联合使用挺好)

    [头文件]#include <string.h> [原型] 1 char *strcat(char *dest, const char *src); [参数]: dest 为目标字符串指针 ...

随机推荐

  1. Mysql常用表管理语句

  2. C# backgroundworker使用方法

    # BackgroundWorker 控件的几个实例(C# backgroundworker使用方法): 在 WinForms 中,有时要执行耗时的操作,在该操作未完成之前操作用户界面,会导致用户界面 ...

  3. CocosBuilder 多分辨率基础

    最近两个项目大量使用了CocosBuilder, 对于开发效率提高是巨大的. 一直计划写一篇博客谈谈CocosBuilder的多分辨率问题, 懒病加上一些疙疙瘩瘩的小事情, 拖延了一个多月, 才终于下 ...

  4. border-radius是向元素添加圆角边框的方法

    border-radius:10px; /* 所有角都使用半径为10px的圆角 */ border-radius: 5px 4px 3px 2px; /* 四个半径值分别是左上角.右上角.右下角和左下 ...

  5. 车大棒浅谈for循环+canvas实现黑客帝国矩形阵

    背景: 一日在网上闲逛的之时,突然看到一个利用JQ插件实现canvas实现的电影黑客帝国的小Demo.觉得创意不错,就下载下来研究一下. 网上浏览jQuery的写法 $(document).ready ...

  6. Bloom Filter的基本原理和变种

    学习一个东西首先要知道这个东西是什么,可以做什么,接着再了解这个东西有什么好处和优势,然后再学习他的工作原理.下面我们分别从这三点简单介绍一下bloom filter,以及和他的变种. What:在允 ...

  7. 第一篇:CUDA 6.0 安装及配置( WIN7 64位 / 英伟达G卡 / VS2010 )

    前言 本文讲解如何在VS 2010开发平台中搭建CUDA开发环境. 当前配置: 系统:WIN7 64位 开发平台:VS 2010 显卡:英伟达G卡 CUDA版本:6.0 若配置不同,请谨慎参考本文. ...

  8. 【原创】梵高油画用深度卷积神经网络迭代十万次是什么效果? A neural style of convolutional neural networks

    作为一个脱离了低级趣味的码农,春节假期闲来无事,决定做一些有意思的事情打发时间,碰巧看到这篇论文: A neural style of convolutional neural networks,译作 ...

  9. JDK分析工具&JVM垃圾回收(转)

    转自:http://blog.163.com/itjin45@126/blog/static/10510751320144201519454/ 官方手册:http://docs.oracle.com/ ...

  10. mybatis关联查询,查询结果多条,却只返回一条记录

    原因是:主表和子表的主键字段相同,可以使用别名!这是因为mybatis的内部实现机制决定的: MyBatis为了降低内存开销,采用ResultHandler逐行读取的JDBC ResultSet结果集 ...