1、malloc
char * str = malloc(8);
1、从高到低分配地址,从低到高存取;
2、上图中上面是栈底,下面是栈顶;
//栈区的变量出了其所属的范围会被系统自动销毁,空间被回收。
//内存数据的清除过程是标记删除,只是标记此块区域可以使用,但是区域内的数据不会被清除。
//函数的调用就是一个进栈出栈的过程
//函数内声明的变量都存储在栈区,包括函数的参数
//内存数据的清除过程是标记删除,只是标记此块区域可以使用,但是区域内的数据不会被清除。
//函数的调用就是一个进栈出栈的过程
//函数内声明的变量都存储在栈区,包括函数的参数
//调用函数时,注意避免返回一个会被系统回收的变量地址。因为栈区的变量出了其所属的范围空间会被回收,如果再通过地址访问,会访问到一个已经不属于这个变量可控的空间。
比如:
#import
<Foundation/Foundation.h>
char func(){ char string[] = "iphone" ; return string;
}
int
main(
int
argc,
const
char
* argv[]) {
char
*a =
func
();
printf("%s", a);
return
0
;
}
|
这里无法输出string[ ] 的内容,因为函数里的变量已经被回收。
#pragma mark-栈内存
#pragma mark-全局区(静态区)
static 修饰的变量存储在全局区(静态区)
1、全局区的变量只初始化一次
2、如果初始值没有给,默认值为0
3、只有程序退出才释放(永远存在)
注意比较:
#import
<Foundation/Foundation.h>
void plus(){ int a = 5 ; a++; printf ( "%d " ,a);
}
int
main(
int
argc,
const
char
* argv[]) {
plus
();
plus (); plus (); return 0 ;
}
|
输出6 6 6
#import
<Foundation/Foundation.h>
void plus(){
static
int a = 5;
a++;
printf ( "%d " ,a);
}
int
main(
int
argc,
const
char
* argv[]) {
plus
();
plus (); plus (); return 0 ;
}
|
输出 6 7 8
#pragma mark-常量区
// 占用内存,只读状态,不能更改
char *string = "iphone" ;
string[ 0 ] = 'a' ;
// 占用内存,只读状态,不能更改
char *string = "iphone" ;
string[ 0 ] = 'a' ;
printf("%s", string);
开辟一个结构体空间以及开辟一个结构体数组空间:
STU
*p =
malloc
(
sizeof
(
STU
));
STU *p1 = malloc(sizeof(STU) * 5);
|
开辟空间必须先计算好所需要的空间,否则超出空间会造成一些问题:
int
*p =
malloc
(
6
);
*p =
4
;
*(p + 1) = 5;//
错误,已超出所开辟的内存空间大小,会覆盖掉所开辟空间之外的内容。
|
释放之前开辟的内存:
free
(void *)
p =
NULL
;
//
释放空间之后讲指针置空,防止多次释放导致程序崩溃(防止野指针错误)。
|
内存泄露
int
*p =
malloc
(
6
);
//指针重指向后,会导致上一块开辟的无法释放,导致
内存泄露
p = malloc(10);
|
小技巧:
把字符类型的数字输出为整型的数字:例如 ‘5’,可以’5’ - ‘0’ = 5,这样就可以输出整型的5了
有一个字符串,其中包含数字,提取其中的数字,要求动态分配内存保存
int
main(
int
argc,
const
char
* argv[]) {
char str[] = "asdf5s54sdfg123" ; int count = 0 ; for ( int i = 0 ; i < strlen (str); i++) { if (str[i] <= '9' && str[i] >= '0' ) { count++; } } int *arr = malloc ( sizeof ( int ) * count); int j = 0 ; for ( int i = 0 ; i < strlen (str); i++) { if (str[i] <= '9' && str[i] >= '0' ) { arr[j] = str[i] - '0' ; j++; }
}
for
(
int
i =
0
; i < count; i++) {
printf ( "%d " , arr[i]);
}
free
(arr);
arr = NULL;
//
记得要释放内存
return
0
;
}
|
calloc(size_t, size_t),
开辟n个size大小的空间,并把开辟空间内的内容清零;
calloc(5, sizeof(int))生成一个5个int类型的空间
char *p = calloc(2, sizeof(int));
realloc(void *, size_t)
,从给定的地址开始,按重新给定的大小开辟空间;如果原有空间往下没有足够的空间可以开辟,系统会重新找到一块可以容纳新空间的地方重新开辟空间,并将原有的内容拷贝到新空间,指针重新赋值。
int
*old_point =
malloc
(
100
);
int *new_point = realloc (old_point, 150 ); printf ( "%p\n" , old_point); printf ( "%p" , new_point);
return 0;
|
memset(void *, int, size_t)
从给定的地址开始,往后
size
个字节,每个字节的内容替换为
int
参数的值。memset一般做清零操作。
生成一个10个char类型的空间,然后把空间用字符a填充:
char
*p =
malloc
(
10
);
memset
(p,
'a'
,
10
);
printf("%s", p);
|
memcpy(void *, const void *, size_t),
从源地址(
const void *
)向目的地址(
void *
)拷贝
siez_t
个字节的内容
char
str[] =
"SHS150609"
;
char *p = malloc ( 20 ); memcpy (p, str + 3 , 6 );
printf("%s", p);
|