内存操作的一些细节收集

一. 内存分配方式有三种:
1. 从静态存储区域分配: 内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。
2. 在栈上创建: 在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 这个大小在linux上可以使用:ulimit -a | grep stack 来查看
3. 从堆上分配: 亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。

char p_arr[] = "p_arr : hello world";
//p_arr是个数组的起始地址,这个数组的内容是存放在栈上面的。另外,非常值得一
//提的是:系统没有为p_arr单独分配一个指针变量用来存放数组p_arr的起始地址。 

char *p_heap=(char *)malloc(sizeof(char)*20);		 
//p_heap是一个指针变量,这个指针变量存在于栈上面,指针变量的值是指向的由
//malloc分配得到的堆上的内存空间的起始地址。

char *ptr = "ptr : hello world";		 
//ptr是一个指针变量,这个指针变量存在于栈上面,指针变量的值是指向的后面字符
//串的起始地址,这个字符串是常量,是存在于静态存储区域的,不是在栈上,也不是在堆上。

二. 向函数传参数时,一般而言,传入非const的指针时,就表示,在函数中要修改这个指针把指内存中的数据。如果是传值,那么无论在函数内部怎么修改这个值,也影响不到传过来的值,因为传值是只内存拷贝。如下:

void GetVersion(char* pStr)
{
    pStr = malloc(10);
    strcpy (pStr, "2.0");
}

main()
{
    char* ver = NULL;
    GetVersion (ver);
    ...
    ...
    free (ver);
}
//程序中妄图通过函数GetVersion给指针ver分配空间,但这种方法根本没有什么作用,
//原因就是——这是传值,不是传指针。

三. strcat, strcpy

extern char* strcat(char *dest,char *src);
//把src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')并添加'\0'。
//src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
//返回指向dest的指针。

char s1[128] = "Hello, "; //error: char* s1 = "Hello, "; 
char* s2 = "world!"; 
char* s3 = strcat(s1, s2);
		
extern char* strcpy(char *dest,const char *src);
//头文件:string.h
//功能:把从src地址开始且含有NULL结束符的字符串赋值到以dest开始的地址空间
//说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串,返回指向dest的指针。

//p 没有分配空间
char *p; 
strcpy(p, "abc");
//没有崩溃,说明运气好p所指向的随机地址对你来说是可写的。

char a[] = "hello";
int len = strlen(a);
char* p = (char*)malloc(sizeof(char)*(len + 1));
strcpy(p, a);
int num = sizeof(a);//等于6,(别忘了还有'\0')
原文地址:https://www.cnblogs.com/fjut/p/2935798.html