问题描述:

 #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. MapReduce深度分析(一)

    MapReduce深度分析(一) 一.数据流向分析 图为MapReduce数据流向示意图 步骤1.输入文件从HDFS流向到Mapper节点.在一般情况下,存储数据的节点就是Mapper运行的节点,不需 ...

  2. datatable 使用详细说明

    要注意的是,要被dataTable处理的table对象,必须有thead与tbody,而且,结构要规整(数据不一定要完整),这样才能正确处理.以下是在进行dataTable绑定处理时候可以附加的参数: ...

  3. HTTP的GET方法模拟

    进行GET方法的测试 #telnet[ ]10.1.1.11[ ]80 GET[ ]/[ ]HTTP/1.0 [两个回车] HEAD[]/[]HTTP/1.0[回车回车] http://www.cnb ...

  4. 使用AIR进行移动APP开发常见功能和问题(上)

    1.  获取最近联系人 思路:侦听Geolocation的update事件,获取经度和纬度信息,再把坐标信息上传至服务器,服务器比较坐标信息算出距离,返回最近位置的若干个人. update时间在2种情 ...

  5. HDU1864(背包)

    最大报销额 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  6. .Net程序员学用Oracle系列(12):增删改查

    1.插入语句 1.1.INSERT 1.2.INSERT ALL 2.删除语句 2.1.DELETE 2.2.TRUNCATE 3.更新语句 3.1.UPDATE 3.2.带子查询的 UPDATE 3 ...

  7. Salesforce的Auto Number

    在Salesforce中新建Object的时候,可以对Name选择Auto Number,即自动编号.如果没有仔细阅读说明的话,会有一个很容易让人迷惑的地方. 在选择时候,Salesforce提供的示 ...

  8. Professional C# 6 and .NET Core 1.0 - 38 Entity Framework Core

    本文内容为转载,重新排版以供学习研究.如有侵权,请联系作者删除. 转载请注明本文出处:Professional C# 6 and .NET Core 1.0 - 38 Entity Framework ...

  9. Tried to obtain the web lock from a thread other than the main thread or the web thread. This may be

    有些操作只能回到主线程操作 比如: mbprogresshud只能在主线程中使用 而且注意凡是关于布局的代码也只能下载主线程

  10. swift2.0 字符串,数组,字典学习代码

    swift 2.0 改变了一些地方,让swift变得更加完善,这里是一些最基本的初学者的代码,里面涉及到swift学习的最基本的字符串,数组,字典和相关的操作.好了直接看代码吧. class View ...