您的位置:首页 > 其它

动态内存分配

2015-08-20 20:26 441 查看
1、malloc   

char * str = malloc(8);

1、从高到低分配地址,从低到高存取;
2、上图中上面是栈底,下面是栈顶;

   
[b]//
栈区的变量出了其所属的范围会被系统自动销毁,空间被回收。

   

//内存数据的清除过程是标记删除,只是标记此块区域可以使用,但是区域内的数据不会被清除。

   

//函数的调用就是一个进栈出栈的过程

   

//函数内声明的变量都存储在栈区,包括函数的参数

   
[/b]
   

[b]//
调用函数时,注意避免返回一个会被系统回收的变量地址。因为栈区的变量出了其所属的范围空间会被回收,如果再通过地址访问,会访问到一个已经不属于这个变量可控的空间。[/b]
比如:

#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';
   

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);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: