printf都做了什么??

最近在看以前的一些代码,发现程序中有一些函数返回指针,而且所返回的指针是stack指针,觉得很是奇怪,stack指针都是系统自己维护,出了作用域以后自动释放的,难道函数所返回的stack指针还能继续使用?以前的代码就是那样,而且运行也一直很正常,这是什么原因?觉得很是怪异。
为测试stack指针是否由系统管理,从函数中返回后是否继续可用,写了一些代码:
// TestPointer.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include 
<windows.h>
#include 
<stdlib.h>

typedef 
struct Person
{
    
int iAge;
    
int iWeight;
}
Person;

//Printf都做了什么?
//感觉调用printf时系统对stack进行了清理
char * GetString(void);
Person 
* GetPerson();

int main(int argc, char* argv[])
{
    printf(
"Hello World!\n");

    
char * pStr = GetString();

    
//感觉调用printf时系统对stack进行了清理
    printf("%s", pStr); //将这一句去掉后运行试试?

    Person 
* m_pPersion = GetPerson();
    
    printf(
"doooooo\n"); //将这一句去掉运行试试?
    printf("Age = %d, Weight = %d\n", m_pPersion->iAge, m_pPersion->iWeight);

    
return 0;
}


char * GetString(void)
{
    
//简单的可以理解为: 
    
//heap:是由malloc之类函数分配的空间所在地。地址是由低向高增长的。 
    
//stack:是自动分配变量,以及函数调用的时候所使用的一些空间。地址是由高向低减少的。
    
//栈(stack)内存的情况
    char szMessage[100];
    strcpy(szMessage, 
"this is just a test!\n");
    printf(
"%s", szMessage);
    
return szMessage;

    
//堆(heap)内存的情况
    /*char * pRet = (char *)malloc( 100 * sizeof(char));
    strcpy(pRet, "This is just a test!\n");
    return pRet;
*/
    
}


Person 
* GetPerson()
{
    
//stack
    Person m_Person;
    m_Person.iAge 
= 24;
    m_Person.iWeight 
= 55;

    
return &m_Person;

    
//更换成heap形式的又是怎样?
}


上述程序运行环境为:WindowsXP sp2 
+ Visual C++ Enterprise Edition 6.0 + Vs6Sp6
源代码

posted on 2008-04-18 20:32 犹志 阅读(1717) 评论(5)  编辑 收藏 引用

评论

# re: printf都做了什么??[未登录] 2008-04-18 21:16 steven

昏。在栈上的数据嘛,肯定没有问题了。  回复  更多评论   

# re: printf都做了什么?? 2008-04-18 22:52 lonkil

你到Release下看看.再用GCC编译一下试试.

我试了这几种情况运行结果都不一样.

说明这种用法存在问题,与printf无关.

应该heap或在调用函数里把空间分配好,传给子函数赋值.  回复  更多评论   

# re: printf都做了什么?? 2008-04-19 01:01 啸天猪

所谓stack自动清理的意思是:函数调用前后调整栈指针(SP)的任务编译器会自动帮你完成

至于指向栈中位置的指针,当然可以随便用,不过这和把指针指向内存位置0一样,后果自负

程序的运行结果无法证明程序的正确性  回复  更多评论   

# re: printf都做了什么?? 2008-04-19 22:03 starofrainnight

這是初學者很容易犯錯誤,想當年我初學C++時也是對這個問題覺得很奇怪。

首先,把棧指針傳遞出來是原則性錯誤,在C++裡是不允許的,而在函數結束後讀取該指針指向的內容的行為是未知的。
其次,棧內存是在函數開始執行時進行分配,在函數結束進行釋放的。
再次,棧內容在函數結束是不會被清理的,因為釋放了的內存不需要再去清理。

但正因為沒有進行清理,在調用此函數後,你馬上讀取該內存,在大部分情況下是可以讀取到原來的內容的,只要沒有其它的程序使用到該塊內存,那些內容是不會改變的,但這種操作是錯誤的,因為該塊內存已經被釋放了,你所讀取的是已經被釋放了的內存的內容。

根據各種編譯器的編譯結果不同,根據系統需要不同,根據你程序編寫的不同,你這個函數所產生的結果是不可預料的,如上,後果自負。  回复  更多评论   

# re: printf都做了什么??[未登录] 2008-05-01 18:51 lynn

starofrainnight说的很对;正如楼主所述,stack使用是由高向低进行的。而您代码中描述的:
char szMessage[100];
strcpy(szMessage, "this is just a test!\n");
数组Message是如此之大,而使用却如此之小,仅"this is just a test!\n"几个字符。这样,存储szMessage时从低址向高址进行,100-22=78个字节尚未使用,退出GetString函数之后。sp指针复原至调用GetString之前的位置。而调用GetPerson的活动记录太小,以至于没有破坏szMessage中存储的22个字符。所以,...
  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

<2008年5月>
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

统计

常用链接

留言簿(1)

随笔分类

随笔档案

文章档案

搜索

最新评论

阅读排行榜

评论排行榜