`
rokuan
  • 浏览: 20403 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

一个C语言指针问题

阅读更多
今天重新拿起C语言的书学习学习,遇到了一个诡异的问题,开始不可理解,现在记录下整个分析过程。
首先上代码:
#include <stdio.h>

void strcopy(char *s, char *t)
{
    while ((*s++ = *t++) != '\0')
    ;
}

int main()
{
    int i = 3;
    char a[] = "abcdefg";
    char *p;	
    strcopy(p, a);
    printf("%d\n",i);
}

我估计大多数人看到这个程序都会认为会打印出3,但是结果出乎意料:


于是我分别做了两次修改,都使程序正常了。
第一次,我把strcopy函数注释掉了
#include <stdio.h>

void strcopy(char *s, char *t)
{
    while ((*s++ = *t++) != '\0')
    ;
}

int main()
{
    int i = 3;
    char a[] = "abcdefg";
    char *p;	
    //strcopy(p, a);
    printf("%d\n",i);
}

打印结果是3.
第二次,我把int i = 3;移动p指针下面定义:
#include <stdio.h>

void strcopy(char *s, char *t)
{
    while ((*s++ = *t++) != '\0')
    ;
}

int main()
{
    char a[] = "abcdefg";
    char *p;	
    int i = 3;
    strcopy(p, a);
    printf("%d\n",i);
}

也得到了正确的结果。
于是我用C free对原来的程序进行调试。

找到变量i的内存地址,可知其存放的是00000003,也就是数字3。
接着我执行strcopy方法后,就出状况了:


结果表明字符串被拷贝到了变量i的内存地址处。我对i处内存的内容进行十六进制转十进制,64636261转十进制后正好是1684234849.也就是这个诡异的输出结果。
综合以上的分析,所得结果如下:
#include <stdio.h>

void strcopy(char *s, char *t)
{
    while ((*s++ = *t++) != '\0')
    ;
}

int main()
{
    int i = 3;    //定义int型变量i,分配内存空间,并赋值
    char a[] = "abcdefg";
    char *p;    //定义指针p,并为初始化指针的位置,在此程序中p默认指向了i的地址
    strcopy(p, a);
    printf("%d\n",i);
}

现在真相大白了,不过任然让我疑惑的在指针p被定义的时候,p的默认指向地址是否有规律可循呢?任旧是个疑问,还请看到这篇文章的各位童鞋指点一二。
不过这个程序本来就是写的有问题,C语言的内存分配果然很容易出错(⊙o⊙)…
我想正确的程序应该是这样的...
#include <stdio.h>

void strcopy(char *s, char *t)
{
    while ((*s++ = *t++) != '\0')
    ;
}

int main()
{
    int i = 3;
    char a[] = "abcdefg";
    char *p = (char *)malloc(sizeof(a));    //给指针分配新的内存空间
    strcopy(p, a);
    printf("%d\n",i);
}

另外,搜索了下,函数malloc()和函数calloc() 的主要区别是前者不能初始化所分配的内存空间,而后者能。
  • 大小: 2.7 KB
  • 大小: 18.7 KB
  • 大小: 18.7 KB
分享到:
评论
28 楼 yangguo 2011-06-30  
学习和研究态度都不错,很有潜力,给你投个精华。
27 楼 jinleileiking 2011-06-30  
chimer 写道
野指针本来就不可预料吧


一些好的编程习惯可以避免野指针
26 楼 kakueiken 2011-06-30  
野指针,值是不可预测的。
不过由于函数堆栈是向上增加的。所以。

char x[]="abcde"
char *p;

打印p的值,很可能吧x的值打印出来了。

函数一开始为函数内部变量分配内存。
比如 上述,sp-7
那么p的地址是 ebp-4
x的地址是ebp-5
由于printf是顺序打印的所以会导致这个原因吧。。。

以上用IDA反汇编一下,可以清楚的看到。
25 楼 rokuan 2011-06-29  
地狱牢笼 写道
rokuan 写道
liusondark 写道
为什么我用VC++运行不了

不太清楚,vc我不太会用,还是比较习惯gcc编译,C Free用的比较顺手

lz有zb的嫌疑
恭喜你,答对了
24 楼 地狱牢笼 2011-06-29  
rokuan 写道
liusondark 写道
为什么我用VC++运行不了

不太清楚,vc我不太会用,还是比较习惯gcc编译,C Free用的比较顺手

lz有zb的嫌疑
23 楼 ray_linn 2011-06-28  
night_stalker 写道
ray_linn 写道
2. t根本就是未分配的地址,这样的拷贝根本随编译器的开心在任一地址中乱写。 微软vc的保护函数在这一方面做出了改进,但是可惜没有成为标准,否则用strcpy_s就能预防这种情况。glibc就比较陈旧了。


讨厌的地方是总提示 strcpy deprecated ...
有时我就是想用 strcpy 啊 ...



这个warning是可以屏蔽的吧,不过我还是会尽量用_s,至少可以防止缓冲区溢出。
22 楼 night_stalker 2011-06-28  
ray_linn 写道
2. t根本就是未分配的地址,这样的拷贝根本随编译器的开心在任一地址中乱写。 微软vc的保护函数在这一方面做出了改进,但是可惜没有成为标准,否则用strcpy_s就能预防这种情况。glibc就比较陈旧了。


讨厌的地方是总提示 strcpy deprecated ...
有时我就是想用 strcpy 啊 ...
21 楼 qforever 2011-06-27  
所有的指针都要初始化,没有初始值,也需要设NULL,不然后患无穷啊
20 楼 chimer 2011-06-27  
野指针本来就不可预料吧
19 楼 rokuan 2011-06-27  
(⊙o⊙)…只是学习过程中碰到的问题做个记录,各位轻拍,还请给新手多一些耐心和指教,不过这个标题的确起的很烂
18 楼 dbaspider 2011-06-27  
哎,典型的缓冲区溢出造成的。。。
17 楼 luckwangjing 2011-06-27  
看到这个帖子让我想起了以前遇到的一个问题!那个问题让我加深了对C语言指针初始化的必要性意识。

首先是定义了一个指针,是忘记了指针初始化。后面经过一系列的操作之后,对该指针进行释放,结果把别的结构体释放掉了一半,这个问题就很奇怪了,被释放的结构体数据错乱了,在经过几天的努力,终于找到了这个问题!当时就真的非常郁闷!后来就习惯性的在定义任何指针的时候都给他置空!

其实LZ这个问题没什么研究的!关于这个指针默认值是怎么分配的,这个和编译器有关,和上下文也有关!
16 楼 panggezi 2011-06-27  
坑爹啊,这C程序写的,一个野指针,你就敢当参数传进去,写内存,还诡异?
15 楼 jkdntc 2011-06-27  
pujia12345 写道
新手 小白吧

p你只定义了一个指针,没有分配变量空间,运行中无意占用了i的空间。

这都不清楚?

一般这样
char str[128];
char * p=str;
strcpy(p,a);



估计是老师教的不好,指针是c语言基础一定要扎实.
14 楼 ppgunjack 2011-06-27  
这个如果情况属实,不是野指针这么简单,栈上分配的指针刚好内容是栈上其他变量的地址,这个巧合概率太低
原来以为是优化导致的栈上变量被寄存器替换导致i,p可能用的同一个寄存器,但是实际编译发觉也不可能出现这种情况
13 楼 eman 2011-06-27  
williamy 写道
感觉 这跟中国的"走进科学"节目一样,
"这个是一个很诡异的C程序"
诡异在何处?
哦,楼主还拿出那么多科学证明过程,
最后的结果是,楼主原来是C语言不好

就像中国西部发生的一件很诡异的事情
一个农民家每天早晨起来都发现鞋子再床上,
经过专家研究,探讨,最后得出结论是,这个农民晚上没洗脚,并且是穿鞋子睡觉的




哈哈,lz应该把《c和指针》多看几遍,野指针而已,基础不扎实,觉得什么都诡异。
12 楼 jackra 2011-06-27  
没有分配空间吗?
刚声明完的指针,会指向那个地址呢?这个问题得问编译器。
11 楼 williamy 2011-06-27  
感觉 这跟中国的"走进科学"节目一样,
"这个是一个很诡异的C程序"
诡异在何处?
哦,楼主还拿出那么多科学证明过程,
最后的结果是,楼主原来是C语言不好

就像中国西部发生的一件很诡异的事情
一个农民家每天早晨起来都发现鞋子再床上,
经过专家研究,探讨,最后得出结论是,这个农民晚上没洗脚,并且是穿鞋子睡觉的


10 楼 ray_linn 2011-06-27  
一个容易犯的错误
CString ReadSomething()
{
   CString str;
   str.format(_T("%s"),"abcdef");
   return str;
}


你会发现有时候是abcdef,有时候是别的东东,这是java程序员写C/C++容易犯的错误
9 楼 silence1214 2011-06-27  
这个就是野指针吧。。。不能说是奇怪,这个情况可能在不同的编译器下出现的结果不一定相同。。你没初始化指针,那么指向哪都有可能的。。不过挺有意思的,让LZ加深了对指针初始化的意识的加强

相关推荐

    C语言指针练习填空和阅读程序题

    C语言指针练习填空和阅读程序题 本资源主要涵盖了C语言指针的相关知识点,包括指针的基本概念、指针运算、指针与数组的关系、指针与字符串的关系等。通过本资源的学习,可以帮助读者更好地理解和掌握C语言指针的...

    c语言指针c语言指针c语言指针c语言指针c语言指针

    c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针c语言指针...

    C语言指针详解.zip

    c语言指针详解 c语言指针详解 c语言指针详解 c语言指针详解 c语言指针详解 c语言指针详解 c语言指针详解 c语言指针详解 c语言指针详解 c语言指针详解 c语言指针详解 c语言指针详解 c语言指针详解 c语言指针详解 ...

    c语言指针学习笔记

    本文将介绍C语言指针的基本概念、定义、初始化、运算以及与一维数组的关系。 首先,我们要理解内存地址的概念。在程序运行时,操作系统为代码和数据分配内存空间,每一个内存单元都有一个唯一的编号,称为内存地址...

    彻底搞定C语言指针————

    C语言指针是C语言中一个非常重要的概念,但它却是初学者最容易迷惑和混淆的部分。要真正搞定C语言指针,需要深入理解C语言变量的存储实质和内存空间的概念。 1. 变量的存储实质 内存空间可以看作是一个存放数据的...

    C语言指针函数和函数指针详细介绍.

    C语言指针函数和函数指针详细介绍 C语言中指针函数和函数指针是两个不同的概念,但它们之间存在着紧密的联系。本文将对C语言中的指针函数和函数指针进行详细的介绍。 一、指针函数 指针函数是指返回值为指针的...

    C语言指针课程PPT

    【C语言指针课程PPT】讲解了C语言中核心的指针概念,它是C语言高效编程的关键。指针允许程序直接访问内存地址,增强了代码的灵活性和性能。以下是关于指针的详细知识点: 1. **变量与内存地址**: - 当在C语言中...

    C语言指针题库

    C语言指针题库 本资源摘要信息是关于C语言指针的题库,涵盖了计算机等级二级考试中的相关内容。该资源包含选择题和编程题,旨在帮助考生和学习者提高C语言指针的知识和技能。 指针基本概念 在C语言中,指针是一种...

    指针详解——介绍C语言指针,看过这个,笔试无忧

    《指针详解——C语言指针完全解析》 在C语言的世界中,指针是一个强大的工具,也是理解和掌握C语言的关键。本文将深入探讨指针的概念、类型、运算及其在笔试中的重要性。 首先,我们要了解什么是指针。指针是一个...

    C语言指针详解 C语言指针详解

    本篇文章将深入探讨C语言指针的各个方面。 首先,我们需要了解指针的声明方式。在声明指针时,我们会指定指针所指向的数据类型。例如: 1. `int *p;` 这里,`p`是一个指针,它指向一个`int`类型的变量。`*`表示...

    c语言指针课件

    c语言 指针 c语言指针课件 c语言指针课件 c语言指针课件 c语言指针课件 c语言指针课件 c语言指针课件 c语言指针课件 c语言指针课件 c语言指针课件 c语言指针课件 c语言指针课件 c语言指针课件 c语言指针课件

    C语言 指针问题 指针问题

    详细讲解了指针的用法和注意事项,指针是我们在学习C语言过程中的一个难点,所以就我个人的一点心得和大家分享一下

    C语言指针详解(通俗易懂).pdf

    C语言中的指针是一个非常核心和重要的概念,它提供了操作内存空间的能力,这对于理解C语言和编写高效的代码至关重要。以下是对文件中提到的知识点的详细解释。 首先,指针概念的基础在于理解变量在内存中的存储方式...

    C语言指针实现字符串的反转

    C语言指针实现字符串的反转 本文主要讨论了使用C语言指针实现字符串的反转的方法,并提供了两个不同的实现程序。 标题解释 "C语言指针实现字符串的反转"这个标题表明本文的主要内容是使用C语言中的指针来实现字符...

    c语言指针完整教程

    c语言指针完整教程 指针不会用 不敢用 你敢说自己会C吗

    C语言指针详解(让你不再惧怕指针)

    在C语言中,指针是一个变量,它存储的是另一个变量的内存地址。当我们声明一个指针变量时,需要指定它所指向的数据类型,例如`int *p;`表示`p`是一个指向整型变量的指针。 接下来是指针的初始化。未初始化的指针...

    精选C语言指针资料大全

    "精选C语言指针资料大全"集合了多种资源,旨在帮助初学者和深入研究者更好地理解和掌握这一核心概念。以下是对这些资源中可能包含的知识点的详细解释。 1. **C指针宝典**: - 指针基础:理解指针是什么,如何声明...

    c语言指针详解,10分钟学会指针用法

    C语言指针详解 C语言指针是一种关键的数据类型,想要学好C语言就必须掌握指针的用法。本篇文章将详细介绍C语言指针的基本概念、指针的声明和使用、数组指针的加减运算、指针之间的运算、指针之间的大小比较、数组...

Global site tag (gtag.js) - Google Analytics