user-0 提问: 这样写c语言真的没事吗

回复:
user: user-1
content: memcpy(ptr,&a,4); //第3个参数是目的指针ptr指向缓冲区的大小，单位字节，而ptr指向的data只有1个字节，这不就写越界了。  int main(void) {     uint8_t data[1];             /* 没有初始化，data[0]='\0';  */     uint8_t*  ptr=data;       /*  OK */     int a = 1;     *ptr++ = 6 ;  /*  相当于把data[0]赋值为6，但这时ptr指针已经指向了下一个字节的位置，这个位置是未知的，不能使用*ptr了  */     memcpy(ptr,&a,4);  /* ptr已经指向未知内存地址，不可随便写，执行效果没有段错误，那是幸运的，这里写了系统的随机内存 */     ptr+=4;     /* 向后移动了4个字节，本身就是指向了随机内存 */     printf("data is %d \n",ptr);   /*  打印随机内存的地址，32位系统上会是个很大的数值 */     return 0; } 要想入门C语言，除了学校里的谭教授那本书，必须看《C和指针》

user: user-2
content: 引用 24 楼 f012011028 的回复:[quote=引用 23 楼 shenyi0106 的回复:] [quote=引用 19 楼 f012011028 的回复:] 楼上的似乎没有说对的 data的空间是在c语言的栈上，而不是堆上，所以不会影响到其他进程，每个进程的栈大小好像是8k，所以你这个程序跑一辈子也不会出错，也不可能影响到别的进程，如果memcpy要是访问到栈之外的空间的话，会发生段错误 例如 while 1       ptr++       memcpy  最后就是段错误结束进程  线程默认栈空间是1M，而非这位兄台所说的8K，如果非要说个8K，那只能说这是64位操作系统的内存页大小。  LZ给的代码运行不会出错，但是会改变变量a的值。  int a = 1;  在实际做项目中，这类错误也时有发生，由于字节对齐的缘故，给一个变量赋值，导致更改了其他变量的值，这类错误一般很难查找。所以应该尽量避免这类写代码的方式。比如用指针作为缓冲区的时候，不管是输入还是输出，都要带一个size参数，以确保不会越界。  当然，这类问题是C/C++程序的“天然特性”，只有通过不断的写，不断的思考，在历练中使错误发生率降到最低[/quote]  栈的大小windows上我不清楚分配多少，linux上默认不会分配到1M 你确定楼主的程序*ptr++ = 6 会改变a的值？[/quote] windows+vs2010改变不了，a和data[]与ptr的组合没有直接关系。我运行的时候a的地址在data的前面，不过也难免什么时候分到后面，ptr++说不定会改变a。不过内存栈一次分多大我觉得不是关键问题，系统有虚拟内存，运行的时候调一部分进去的

user: user-3
content: 引用 5 楼 u010848119 的回复:之所以能够正常运行，是因为main函数里面修改的那段内存还没有被别的地方使用，如果程序中有另外一个变量需要访问这段内存中的内容，而实际这段内容已经被你的函数修改了，这时候就会出错。 建议：1.变量定义要初始化；2.对数组下标做合法性判断；3.做好越界、内存溢出等防护措施；4.使用memcpy需谨慎。

user: user-4
content: 引用 23 楼 shenyi0106 的回复:[quote=引用 19 楼 f012011028 的回复:] 楼上的似乎没有说对的 data的空间是在c语言的栈上，而不是堆上，所以不会影响到其他进程，每个进程的栈大小好像是8k，所以你这个程序跑一辈子也不会出错，也不可能影响到别的进程，如果memcpy要是访问到栈之外的空间的话，会发生段错误 例如 while 1       ptr++       memcpy  最后就是段错误结束进程  线程默认栈空间是1M，而非这位兄台所说的8K，如果非要说个8K，那只能说这是64位操作系统的内存页大小。  LZ给的代码运行不会出错，但是会改变变量a的值。  int a = 1;  在实际做项目中，这类错误也时有发生，由于字节对齐的缘故，给一个变量赋值，导致更改了其他变量的值，这类错误一般很难查找。所以应该尽量避免这类写代码的方式。比如用指针作为缓冲区的时候，不管是输入还是输出，都要带一个size参数，以确保不会越界。  当然，这类问题是C/C++程序的“天然特性”，只有通过不断的写，不断的思考，在历练中使错误发生率降到最低[/quote]  栈的大小windows上我不清楚分配多少，linux上默认不会分配到1M 你确定楼主的程序*ptr++ = 6 会改变a的值？

user: user-5
content: 引用 19 楼 f012011028 的回复:楼上的似乎没有说对的 data的空间是在c语言的栈上，而不是堆上，所以不会影响到其他进程，每个进程的栈大小好像是8k，所以你这个程序跑一辈子也不会出错，也不可能影响到别的进程，如果memcpy要是访问到栈之外的空间的话，会发生段错误 例如 while 1       ptr++       memcpy  最后就是段错误结束进程  线程默认栈空间是1M，而非这位兄台所说的8K，如果非要说个8K，那只能说这是64位操作系统的内存页大小。  LZ给的代码运行不会出错，但是会改变变量a的值。  int a = 1;  在实际做项目中，这类错误也时有发生，由于字节对齐的缘故，给一个变量赋值，导致更改了其他变量的值，这类错误一般很难查找。所以应该尽量避免这类写代码的方式。比如用指针作为缓冲区的时候，不管是输入还是输出，都要带一个size参数，以确保不会越界。  当然，这类问题是C/C++程序的“天然特性”，只有通过不断的写，不断的思考，在历练中使错误发生率降到最低

user: user-4
content: 引用 21 楼 zaoqitouteng 的回复:大哥，使用内置的数组类型还敢把指针这样移动无异于自杀啊，以后用指针就记着两点，数组名和大小，不然就跟埋了地雷一样说不定哪天就 “boom”!  我没说可以这么用，我就把把这块的道理告他他

user: user-2
content: 大哥，使用内置的数组类型还敢把指针这样移动无异于自杀啊，以后用指针就记着两点，数组名和大小，不然就跟埋了地雷一样说不定哪天就 “boom”!

user: user-4
content: 楼主结贴！分给我就完事了

user: user-4
content: 楼上的似乎没有说对的 data的空间是在c语言的栈上，而不是堆上，所以不会影响到其他进程，每个进程的栈大小好像是8k，所以你这个程序跑一辈子也不会出错，也不可能影响到别的进程，如果memcpy要是访问到栈之外的空间的话，会发生段错误 例如 while 1       ptr++       memcpy  最后就是段错误结束进程

user: user-6
content: 引用 5 楼 u010848119 的回复:之所以能够正常运行，是因为main函数里面修改的那段内存还没有被别的地方使用，如果程序中有另外一个变量需要访问这段内存中的内容，而实际这段内容已经被你的函数修改了，这时候就会出错。 建议：1.变量定义要初始化；2.对数组下标做合法性判断；3.做好越界、内存溢出等防护措施；4.使用memcpy需谨慎。

user: user-7
content: 违法不一定被抓。 但不说明违法没有问题。

user: user-8
content: 引用 11 楼 jim5197 的回复:[quote=引用 10 楼 xihu1364 的回复:] 不是你的东西你在用，你说可以不？  你的合法老婆被别人正当的用，你愿意不 这你都能联想起来，你的合法老婆肯定被人用过了。而且看样子你还不知道[/quote]  只是打比方，用得着这么认真....  用了不属于你的东西，发生什么后果...就不可预知了

user: user-7
content: 区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。  在你防采花功力还不济的时候，你的老婆是不是被别人用过你也无从知晓。 在你采花功力还不济的时候，用别人的老婆的后果就会很严重。  采花大盗必备工具： OpenProcessToken LookupPrivilegeValue AdjustTokenPrivileges CloseHandle OpenProcess ReadProcessMemory VirtualQueryEx VirtualProtectEx WriteProcessMemory CloseHandle

user: user-0
content: 引用 10 楼 xihu1364 的回复:不是你的东西你在用，你说可以不？  你的合法老婆被别人正当的用，你愿意不 这你都能联想起来，你的合法老婆肯定被人用过了。而且看样子你还不知道

user: user-8
content: 不是你的东西你在用，你说可以不？  你的合法老婆被别人正当的用，你愿意不

user: user-9
content: 1.程序是错的。 2.应用层的程序内存空间独立，一般是影响不了其他程序的。

user: user-0
content: 引用 6 楼 zhao4zhong1 的回复:其实电脑开机后物理内存的每个字节都是可读写的，从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。 老师 您好  1、那这样写是没有问题的吗？ 2、如果这样写没有问题，我直接用指针去访问没有分配的内存就像上例中ptr，万一访问到其他程序的内存怎么办？

user: user-7
content: 使用API ReadProcessMemor和WriteProcessMemory还能读写其它进程的内存呢！

user: user-7
content: 其实电脑开机后物理内存的每个字节都是可读写的，从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

user: user-10
content: 之所以能够正常运行，是因为main函数里面修改的那段内存还没有被别的地方使用，如果程序中有另外一个变量需要访问这段内存中的内容，而实际这段内容已经被你的函数修改了，这时候就会出错。 建议：1.变量定义要初始化；2.对数组下标做合法性判断；3.做好越界、内存溢出等防护措施；4.使用memcpy需谨慎。