当一个程序执行时,需要用一定的内存空间用于存放程序执行中使用到的各种数据。按内存空间分配方式的不同,一个程序所使用的内存区域可以分为静态内存和动态内存。在程序开始运行时由系统分配的内存称为静态内存,在程序运行过程中由用户自己申请分配内存称为动态内存。
使用静态内存对于用户来说是很方便的。用户并不需要了解分配内存的具体细节,也不需要考虑由于程序结束前未释放所占用的内存空间而带来的可用内存泄露。同时,静态内存也是不通过指针而使用变量的唯一方法。
但是静态内存也存在着一定的缺陷:
- 静态内存总是预先定义了存放数据的数组大小,这就有可能是传入的数据量大过数组容量而发出溢出问题 。对于定义过大的数组就会是内存空间的一种浪费。
- 其次,由于某个函数中的栈内存将在此函数结束时被释放,使用指针由子函数向父函数传递数据是无法实现的。
下面用例子来说明这一点:
#include <stdio.h>
#include <string.h>
//Function decalration
char *newstring(char *str1);
int main(void)
{
char *str1;
str1 = "hello world";
str1 = newstring(str1);
printf("%s\n", str1);
return 0;
}
//Define function
char *newstring(char *str1)
{
int i;
char arr[100];
strcpy(arr, str1);
for(i = 0; i < strlen(arr); i++){
arr[i] = 'k';
}
return arr;
}
例子在定义函数newstring中返回在此函数中定义的局部变量(属于栈内存),因为在此函数结束的时候此变量就被系统释放了,不会得到用户期望的结果。
在linux下用gcc 编译此源文件会得到以下的警告:
这个错误就是说在函数newstring中返回了一个局部本地的变量(栈内存)。所以在子函数中传址的时候要注意到这一点。
see_var.c: In function 'newstring':
see_var.c:32: warning: function returns address of local variable
see_var.c: In function 'newstring':
see_var.c:32: warning: function returns address of local variable
see_var.c: In function 'newstring':
see_var.c:32: warning: function returns address of local variable
因为在子函数中返回的是一个栈地址,栈地址的内容在子函数结束后会被自动回收。使用这样一个地址的内容是危险的,编译器首先要报警告,其次在程序运行过程中也可能会遇到不可预测的错误。