zoukankan      html  css  js  c++  java
  • C语言讲义——内存管理

    动态分配内存

    动态分配内存,在堆(heap)中分配。

    void *malloc(unsigned int num_bytes);
    
    • 头文件 stdlib.h或malloc.h
    • 向系统申请分配size个字节的内存空间
    • 返回void* 类型(未确定类型的指针)
    • 可强制转换为任何类型的指针
    void *memset(void *s,int c,size_t n)
    
    • 头文件 string.h或memory.h
    • 将内存空间s的前n个字节的值设为值c
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    void getResult(char *pp) {
    	pp = (char *)malloc(10);
    	memset(pp, 0, 10);
    	strcpy(pp, "函数内");
    }
    void testMalloc() {
    	char *p = NULL;
    	getResult(p);
    	printf("getResult()后:%s
    ", p);
    
    	p = (char *)malloc(10);
    	memset(p, 0, 10);
    	strcpy(p, "调用方");
    	printf("%s
    ", p);
    }
    
    int main(int argc, char *argv[]) {
    	testMalloc();
    	return 0;
    }
    

    二级指针

    二级指针——指向指针的指针

    如果要在函数中申请内存,调用放还想得到申请的新内存的话,需要使用二级指针:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    const int g_size = 20;
    
    //申请新的内存空间
    void _exploit(char **pp) {
    	*pp = (char *)malloc(g_size);
    	memset(*pp, 0, g_size);
    	strcpy(*pp, "函数内的新空间");
    }
    
    //释放内存空间
    void _giveBack(char **pp) {
    	if (*pp != NULL) {
    		free(*pp);
    		*pp = NULL;
    	}
    }
    
    main() {
    	char *p = NULL;
    	_exploit( &p );
    	printf("【%s】
    ", p);
    	_giveBack(&p);
    	printf("【%s】
    ", p);
    
    	p = (char *)malloc(g_size);
    	memset(p, 0, g_size);
    	strcpy(p, "调用方的新空间");
    	printf("【%s】
    ", p);
    	_giveBack(&p);
    	printf("【%s】
    ", p);//不加【】不打印(null),加了才打印
    }
    

    lloc系列函数

    malloc 动态分配内存,需要与memset配合使用
    calloc 动态分配完内存后,自动初始化内存空间为零
    realloc 为数组重新分配内存
    #include<stdio.h>
    #include<stdlib.h>
    main() {
        char *p = NULL;
        printf("p:%s
    ", p);
        p = (char *)malloc(10);
        printf("p:%s
    ", p);
        if (p!=NULL) {
            free(p);
            p=NULL;
        }
        p = (char *)calloc(10,sizeof(char));
        printf("p:%s
    ", p);
        if (p!=NULL) {
            free(p);
            p=NULL;
        }
        printf("p:%s
    ", p);
    }
    
    #include <stdio.h>
    main() {
    	char arr[3];
    	int n = 1;
    	int i = 1;
    	printf("n = %d
    ", n);
    	char *p = &arr[0];
    	char *p2 = realloc(p, 10);
    	for(i = 0; i<10; i++) {
    		arr[i] = 9;
    	}
    	printf("n = %d
    ", n);
    }
    

    释放内存

    • malloc等内存分配函数开辟的内存来自于堆(heap),
    • 堆是有限的,不能只开辟,不释放,
    • 使用free函数释放不使用的内存。

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    void testMalloc() {
    	char *p = (char *)malloc(10);
    	memset(p, 0, 10);
    	strcpy(p, "调用方");
    	printf("p:%s
    ", p);
    	if(p != NULL) {
    		free(p);
    		p = NULL;
    	}
    	printf("p:%s
    ", p);
    }
    
    int main(int argc, char *argv[]) {
    	testMalloc();
    	return 0;
    }
    

    示例:猜价格

    知识点:

    • 内存管理
    • 二级指针
    • 循环
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    int getResult(int n, char **pp) {
    	int nRealPrice = 2999;
    	*pp = (char *)malloc(10);
    	memset(*pp, 0, 10);
    	if (n > nRealPrice) {
    		strcpy(*pp, "高了");
    		return 0;
    	} else if (n < nRealPrice) {
    		strcpy(*pp, "低了");
    		return 0;
    	} else {
    		strcpy(*pp, "正确");
    		return 1;
    	}
    }
    
    void setFree(char **pp) {
    	if(*pp != NULL) {
    		free(*pp);
    		*pp = NULL;
    	}
    }
    
    void guessPrice() {
    	int n = 0;
    	char *p = NULL;
    	int nRet = 0;
    
    	do {
    		scanf("%d", &n);
    		nRet = getResult(n, &p);
    		printf("p:%s
    ", p);
    
    		setFree(&p);
    		printf("p:%s
    ", p);
    	} while(nRet == 0 );
    }
    int main(int argc, char *argv[]) {
    	guessPrice();
    	return 0;
    }
    

    模拟Java的ArrayList的add()方法

    ArrayList又叫动态数组,长度不够的时候可以自动申请新的内存。

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    static int capacity = 3;
    static int index = 0;
    void foreach(char * p) {
    	puts("");
    	for(int i = 0; i<=index; i++) {
    		printf("%c ", *(p+i));
    	}
    	puts("");
    }
    void add(char **p, char c) {
    	if (*p == NULL) {
    		*p = (char*)calloc(capacity, sizeof(char));
    	} else {
    		if(index >= capacity ) {
    			capacity += (capacity>>1);
    			printf("新容量:%d 
    ", capacity);
    			char *p2 = (char*)realloc(*p, capacity);
    			//free(*p);
    			*p = p2;
    		}
    	}
    	*(*p+index) = c;
    	index++;
    	//printf("index = %d 
    ",index);
    }
    main() {
    	char* p = NULL;
    	int n = 1000;
    	for(int i = 0; i<20; i++) {
    		add(&p, 'A');
    		foreach(p);
    	}
    	printf("int = %d    
    ", n);
    }
    
  • 相关阅读:
    jquery select操作和联动操作
    chrome 31删除输入框的历史记录
    14、python开发之路-并发编程之I/O模型
    13、python开发之路-并发编程之多线程
    12、python全栈之路-并发编程之多进程
    11、python全栈之路-网络编程
    10、python全栈之路-面向对象进阶
    9、python全栈之路-模块与包
    8、python全栈之路-初识面向对象
    6、python全栈之路-常用模块
  • 原文地址:https://www.cnblogs.com/tigerlion/p/11191604.html
Copyright © 2011-2022 走看看