先来分析两个表达式
1.char s1[] = "helloworld";  //helloworld是在运行时刻赋值的;
2.char *s2 = "nihaoshijie"; //nihaoshijie是在编译时就确定的,默认放在常量区;
注:我这里说的都是字符串而S1和S2都在栈上,不要混淆。
#include <stdio.h>
char* GetMemory_point()
{
    char* string = "hello,world";
    char array[] = "nihao,shijie";
    return string;
}
/*char* GetMemory_array()
{
    char array[] = "nihao,shijie";
    return array;
}*/
int main(void)
{
    char *ret_point = GetMemory_point();
//    char *ret_array = GetMemory_array();
    printf("%s\n",GetMemory_point());
//    printf("%s\n",ret_array);
    return 0;
}
/*程序想要做到在子函数中声明一个字符串并在主函数中将其打印出来*/
GetMemory_array()函数无法完成,因为此数组是分配在栈上的,所以子函数结束后就会消失。如图
程序在内存中的分布(今天的一个问题)_内存
char *string ="hello,world"; 虽然 p存放于stack,可是其值表示的是常量区的地址,所以其指向的内容不会因为函数退出而销毁。
注:从gdb显示的的内存分配可以看出string存放在地址0x8048580位置,大概就是.rodata区而array则是放在地址0xbffff25f的位置,就是栈的区域。
再来看看我今天的一个错误:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void print_tokens(char* line)
{
    static const char whitespace[] = " \t\f\r\v\n";
    char* token;
    for(token = strtok(line,whitespace);
            token;
            token = strtok(NULL,whitespace))
    printf("Next token is %s \n",token);
}
int main(void)
{
//    char test[] = "hello world    ni\
                  hao shijie";
    char* string = "hello world nihao shijie";
    char test[] = "hello world nihao shijie";
    print_tokens(test);
    return 0;
程序在内存中的分布(今天的一个问题)_程序_02
       此函数想要从字符串中分离出单词,但是当strtok函数执行任务时,它将会修改它所处理的字符串,如果源字符串不能被修改,那就复制一份,将这份拷贝传递给strtok 。故在此函数中string在.rodata区是不可修改的,而test的形式是在栈上故可以成功
现总结如下(来源于网络)
内存分配方式有三种:
(1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。
(2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
(3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。
//main.cpp
int a = 0; 全局初始化区 (.data)
char *p1; 全局未初始化区 (.bss)
main()
{
int b; 栈
char s[] = "abc"; 栈
char *p2; 栈
char *p3 = "123456"; 123456\0在常量区,p3在栈上。
static int c =0; 全局(静态)初始化区 (.data)
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
分配得来得10和20字节的区域就在堆区。
strcpy(p1, "123456"); 123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。
}