问题描述:

 #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. social relation & recommender system

    由于社交网络盛行,现在许多关于推荐系统的研究都考虑了如何使用social relation来改进推荐系统.虽然有很多论文都成功的使用social relation改进了推荐效果,然而,也有一些尝试失败 ...

  2. oracle语句总结(一)

    1,建外键 新建两个表来实现外键的关联. create table main_tab ( id number, name varchar2(30) ); create table sub_tab ( ...

  3. abstract、override、new、virtual、sealed使用和示例

    abstract修饰类名为抽象类,修饰方法为抽象方法.如果一个类为抽象类,则这个类智能是其他某个类的基类.抽象方法在抽象类中没有函数体.抽象类中的抽象方法是没有方法体的,继承其的子类必须实现抽象类的抽 ...

  4. CodeForces757B

    B. Bash's Big Day time limit per test 2 seconds memory limit per test 512 megabytes input standard i ...

  5. Hadoop权威指南:从Hadoop URL读取数据

    [TOC] Hadoop权威指南:从Hadoop URL读取数据 使用java.net.URL对象从Hadoop文件系统读取文件 实现类似linux中cat命令的程序 文件名 HDFSCat.java ...

  6. Python学习--20 Web开发

    HTTP格式 HTTP协议是基于TCP和IP协议的.HTTP协议是一种文本协议. 每个HTTP请求和响应都遵循相同的格式,一个HTTP包含Header和Body两部分,其中Body是可选的. HTTP ...

  7. (转)java二维数组的深度学习(静态与动态)

    转自:http://developer.51cto.com/art/200906/128274.htm,谢谢 初始化: 1.动态初始化:数组定义与为数组分配空间和赋值的操作分开进行:2.静态初始化:在 ...

  8. 负笈前行--DPDK代码风格

    每个公司都会有自己代码风格或者编程规范,都旨在防范编程语言的一些陷阱或者提高代码效率,还有就是保持一致编码风格来提高代码可读性,方便code review: 或者说代码的一种美学,比如python也就 ...

  9. React 笔记

    跟我一起学 React

  10. DLL 导出函数

    DLL的链接方式分为两种:隐式链接和显式链接 DLL导出的函数 和 导出类在调用时,有些区别,这里暂时不讲,直说简单的导出函数: 隐式链接: #include "stdafx.h" ...