作者:犹志 来源:C++博客 酷勤网收集 2008-04-20
摘要
发现程序中有一些函数返回指针,而且所返回的指针是stack指针,觉得很是奇怪,stack指针都是系统自己维护,出了作用域以后自动释放的,难道函数所返回的stack指针还能继续使用?以前的代码就是那样,而且运行也一直很正常,这是什么原因?觉得很是怪异。
最近在看以前的一些代码,发现程序中有一些函数返回指针,而且所返回的指针是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
源代码
为测试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评论
# 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++裡是不允許的,而在函數結束後讀取該指針指向的內容的行為是未知的。
其次,棧內存是在函數開始執行時進行分配,在函數結束進行釋放的。
再次,棧內容在函數結束是不會被清理的,因為釋放了的內存不需要再去清理。
但正因為沒有進行清理,在調用此函數後,你馬上讀取該內存,在大部分情況下是可以讀取到原來的內容的,只要沒有其它的程序使用到該塊內存,那些內容是不會改變的,但這種操作是錯誤的,因為該塊內存已經被釋放了,你所讀取的是已經被釋放了的內存的內容。
根據各種編譯器的編譯結果不同,根據系統需要不同,根據你程序編寫的不同,你這個函數所產生的結果是不可預料的,如上,後果自負。
来自:http://www.cppblog.com/guan98413/archive/2008/04/18/47530.html

