常德水鱼村 发表于 2023-8-29 11:12:38

内存分布的问题?请高手帮忙解答一下

在学习Linux、Windows下C语言内存布局(内存模型)的时候有些疑惑。
示例代码

1.   #include <stdio.h>
2.
3.    char *str1 = "biancheng"; //字符串在常量区,str1 在全局数据区
4.    int n; //全局数据区
5.
6.    char* func(){
7.            char *str = "C 语言"; //字符串在常量区,str 在栈区
8.            return str;
9.    }
10.
11.    int main(){
12.          int a; //栈区
13.               char *str2 = "01234"; //字符串在常量区,str2 在栈区
14.           char arr = "56789"; //字符串和 arr 都在栈区
15.           char *pstr = func(); //栈区
16.            int b; //栈区
17.
18.           printf("str1: %#X\npstr: %#X\nstr2: %#X\n", str1, pstr, str2);
19.           puts("--------------");
20.           printf("&str1: %#X\n &n: %#X\n", &str1, &n);
21.           puts("--------------");
22.            printf(" &a: %#X\n arr: %#X\n &b: %#X\n", &a, arr, &b);
23.           puts("--------------");
24.            printf("n: %d\na :%d\nb: %d\n", n, a, b);
25.           puts("--------------");
26.            printf("%s\n", pstr);
27.
28.           return 0;
29.    }



问题一:表达式的左值和右值都在相应的内存区域么?
例如上面代码,第3行str,左值全局变量是在全局数据区,str是一块内存的标记么?标记的这块内存存的是指向字符串常量的地址么?右边值是字符串常量"C 语言" 在常量区,是在常量区的内存上,内存上记录的是“C语言”还是指向“C语言”的地址。


问题二:那他们之间是如何指向的,是编译规定还是硬件规定,还是系统规定?

isdkz 发表于 2023-8-29 11:13:24

问题一:表达式的左值和右值都在相应的内存区域。

在上面的代码中,第3行的表达式 char *str1 = "biancheng"; 中,左值 str1 是一个全局变量,它在全局数据区。右值 "biancheng" 是一个字符串常量,它在常量区。左值 str1 存储的是指向字符串常量 "biancheng" 的地址。

在第6行的函数 func() 中,左值 str 是一个局部变量,它在栈区。右值 "C 语言" 是一个字符串常量,它在常量区。左值 str 存储的是指向字符串常量 "C 语言" 的地址。

在第13行的表达式 char *str2 = "01234"; 中,左值 str2 是一个局部变量,它在栈区。右值 "01234" 是一个字符串常量,它在常量区。左值 str2 存储的是指向字符串常量 "01234" 的地址。

在第14行的表达式 char arr = "56789"; 中,左值 arr 是一个数组变量,它在栈区。右值 "56789" 是一个字符串常量,它也在栈区。左值 arr 存储的是字符串常量 "56789" 的拷贝。

问题二:它们之间的指向是编译规定。

编译器会根据代码的语法规则和语义规则来确定表达式的左值和右值的存储位置。左值通常是可被赋值的变量或内存区域,而右值通常是常量或表达式的计算结果。编译器会根据变量的作用域、生命周期和类型等信息来分配内存空间,并将右值存储到相应的内存区域中。

硬件和操作系统也会对内存分布有一定的规定,但在这个问题中,左值和右值的存储位置是由编译器决定的,而不是硬件或操作系统规定的。编译器会根据编程语言的规范和编译器的实现来确定内存分布。
页: [1]
查看完整版本: 内存分布的问题?请高手帮忙解答一下