动态内存分配

来源:互联网 发布:淘宝侵犯肖像权扣几分 编辑:程序博客网 时间:2024/06/06 12:54
1、malloc   

char * str = malloc(8);

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

   //栈区的变量出了其所属的范围会被系统自动销毁,空间被回收。
   
//内存数据的清除过程是标记删除,只是标记此块区域可以使用,但是区域内的数据不会被清除。
   
//函数的调用就是一个进栈出栈的过程
   
//函数内声明的变量都存储在栈区,包括函数的参数
   
   //调用函数时,注意避免返回一个会被系统回收的变量地址。因为栈区的变量出了其所属的范围空间会被回收,如果再通过地址访问,会访问到一个已经不属于这个变量可控的空间。
比如:

#import<Foundation/Foundation.h>
charfunc(){
   
char string[] = "iphone";
   
return string;
}
intmain(intargc, 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>
voidplus(){
   
int a = 5;
    a++;
   
printf("%d ",a);
}

intmain(intargc, const char * argv[]) {
    plus();
   
  plus();
   
  plus();
 return0;
}

输出6 6 6


#import<Foundation/Foundation.h>
voidplus(){
   static inta = 5;
    a++;
   
printf("%d ",a);
}

intmain(intargc, const char * argv[]) {
    plus();
   
plus();
   
plus();
 return0;
}
输出 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了

有一个字符串,其中包含数字,提取其中的数字,要求动态分配内存保存

intmain(intargc, const char * argv[]) {
   
char str[] = "asdf5s54sdfg123";
   
int count = 0;
   
for (inti = 0; i <strlen(str); i++) {
       
if (str[i] <= '9' && str[i] >= '0') {
            count++;
        }
    }
   
int *arr = malloc(sizeof(int) * count);
   
int j = 0;
   
for (inti = 0; i <strlen(str); i++) {
       
if (str[i] <= '9' && str[i] >= '0') {
            arr[j] = str[i] -
'0';
            j++;
        }
    }   
   for (inti = 0; i < count; i++) {
       
printf("%d ", arr[i]);
    } 
    free(arr);
     arr =NULL;//记得要释放内存
   return 0;
}

   calloc(size_t, size_t),开辟nsize大小的空间,并把开辟空间内的内容清零;
   calloc(5, sizeof(int))生成一个5int类型的空间
   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);
0 0