当我声明这个字符指针数组时,内存是如何组织的? "char* op[30]"
How the memory is organized when I declare this array of chars pointer? "char* op[30]"
该代码(C 语言)如何工作?我不明白那段代码“char* op[30]”分配了多少内存。而且我也不知道在那种情况下记忆是如何组织的。我知道如何使用“malloc”分配内存,但下面的情况对我来说是模糊的。
int main(void) {
int n;
scanf("%i", &n);
char* op[30];
op[0] = "Hello, World"
op[1] = "Hello, World World World"
op[2] = "Hello, World World World World World World"
op[3] = "Hello, World World World World World World World World World..."
printf("%s\n", op[0]);
printf("%s\n", op[1]);
printf("%s\n", op[2]);
printf("%s\n", op[3]);
return 0;
}
您将在堆栈上有一个长度为 30 的连续数组。该数组的每个元素都是一个 char* 指针。前 4 个指针分别指向一个文字字符串。其他条目未初始化
恢复声誉
char* op[30];
在 heap. In this case you just say to compiler that you are going to store 30 pointers to char arrays; of course @pm100 上分配是正确的。 char *op[30] 在堆栈上分配,因为它是一个数组,所以它表示为一块内存
- 另一方面,字符串是静态定义的,编译器已经知道如何将它们放在内存中。
char *x
; 没错。如果我们谈论 MCU 的固件,您的字符串将被写入闪存。在 op[1] 的初始化过程中 - op[3] 分配字符串第一个元素的地址
- 将内存视为一个 linked list; @pm100 纠正我,如果我错了,但是堆内存管理看起来像链表
- 一一总结1-3个字符串,当你为数组的元素内存管理系统分配新值时,搜索最后一个字符串的结尾并将新字符串放在它旁边; 忘了
- 您的代码不安全。以这种方式定义的字符串数组没有限制,数据可能会损坏; 又错了
- 当您使用
malloc
时,您告诉内存管理系统在堆上查找具有所需大小的固定内存块。内存管理器,如果可能保留块,将其添加到列表末尾 (#2) 和 returns 你指向该块起始地址的指针。
要玩的代码:
#include <stdio.h>
#include <string.h>
int main(void)
{
char* op[30];
op[0] = "Hello, World";
op[1] = "Hello, World World World";
op[2] = "Hello, World World World World World World";
op[3] = "Hello, World World World World World World World World World...";
printf("mem:0x%04X >> %u - %u >> %s\n", op[0], 0, strlen(op[0]), op[0]);
printf("mem:0x%04X >> %u - %u >> %s\n", op[1], (op[1]-op[0]), strlen(op[1]), op[1]);
printf("mem:0x%04X >> %u - %u >> %s\n", op[2], (op[2]-op[1]), strlen(op[2]), op[2]);
printf("mem:0x%04X >> %u - %u >> %s\n\n", op[3], (op[3]-op[2]), strlen(op[3]), op[3]);
/* save pointer to op[1] */
char *tmp_string = op[1];
/* overrite op[1] */
op[1] = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. ";
printf("mem:0x%04X >> %u - %u >> %s\n", op[0], 0, strlen(op[0]), op[0]);
printf("mem:0x%04X >> %u - %u >> %s\n", op[1], (op[1]-op[0]), strlen(op[1]), op[1]);
printf("mem:0x%04X >> %u - %u >> %s\n", op[2], (op[2]-op[1]), strlen(op[2]), op[2]);
printf("mem:0x%04X >> %u - %u >> %s\n", op[3], (op[3]-op[2]), strlen(op[3]), op[3]);
printf("TMP String: mem:0x%04X >> %s\n", tmp_string, tmp_string);
op[29] = "dolor sit amet, consectetur adipiscing elit";
printf("mem:0x%04X >> %u - %u >> %s\n\n\n", op[29], (op[29]-op[3]), strlen(op[29]), op[29]);
/* print mem layout */
for(int i = 0; i < 30; i++) {
printf("mem:0x%04X >> op[%u]\n", op[i], i);
}
return 0;
}
该代码(C 语言)如何工作?我不明白那段代码“char* op[30]”分配了多少内存。而且我也不知道在那种情况下记忆是如何组织的。我知道如何使用“malloc”分配内存,但下面的情况对我来说是模糊的。
int main(void) {
int n;
scanf("%i", &n);
char* op[30];
op[0] = "Hello, World"
op[1] = "Hello, World World World"
op[2] = "Hello, World World World World World World"
op[3] = "Hello, World World World World World World World World World..."
printf("%s\n", op[0]);
printf("%s\n", op[1]);
printf("%s\n", op[2]);
printf("%s\n", op[3]);
return 0;
}
您将在堆栈上有一个长度为 30 的连续数组。该数组的每个元素都是一个 char* 指针。前 4 个指针分别指向一个文字字符串。其他条目未初始化
恢复声誉
char* op[30];
在 heap. In this case you just say to compiler that you are going to store 30 pointers to char arrays; of course @pm100 上分配是正确的。 char *op[30] 在堆栈上分配,因为它是一个数组,所以它表示为一块内存- 另一方面,字符串是静态定义的,编译器已经知道如何将它们放在内存中。
char *x
; 没错。如果我们谈论 MCU 的固件,您的字符串将被写入闪存。在 op[1] 的初始化过程中 - op[3] 分配字符串第一个元素的地址 - 将内存视为一个 linked list; @pm100 纠正我,如果我错了,但是堆内存管理看起来像链表
- 一一总结1-3个字符串,当你为数组的元素内存管理系统分配新值时,搜索最后一个字符串的结尾并将新字符串放在它旁边; 忘了
- 您的代码不安全。以这种方式定义的字符串数组没有限制,数据可能会损坏; 又错了
- 当您使用
malloc
时,您告诉内存管理系统在堆上查找具有所需大小的固定内存块。内存管理器,如果可能保留块,将其添加到列表末尾 (#2) 和 returns 你指向该块起始地址的指针。
要玩的代码:
#include <stdio.h>
#include <string.h>
int main(void)
{
char* op[30];
op[0] = "Hello, World";
op[1] = "Hello, World World World";
op[2] = "Hello, World World World World World World";
op[3] = "Hello, World World World World World World World World World...";
printf("mem:0x%04X >> %u - %u >> %s\n", op[0], 0, strlen(op[0]), op[0]);
printf("mem:0x%04X >> %u - %u >> %s\n", op[1], (op[1]-op[0]), strlen(op[1]), op[1]);
printf("mem:0x%04X >> %u - %u >> %s\n", op[2], (op[2]-op[1]), strlen(op[2]), op[2]);
printf("mem:0x%04X >> %u - %u >> %s\n\n", op[3], (op[3]-op[2]), strlen(op[3]), op[3]);
/* save pointer to op[1] */
char *tmp_string = op[1];
/* overrite op[1] */
op[1] = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. ";
printf("mem:0x%04X >> %u - %u >> %s\n", op[0], 0, strlen(op[0]), op[0]);
printf("mem:0x%04X >> %u - %u >> %s\n", op[1], (op[1]-op[0]), strlen(op[1]), op[1]);
printf("mem:0x%04X >> %u - %u >> %s\n", op[2], (op[2]-op[1]), strlen(op[2]), op[2]);
printf("mem:0x%04X >> %u - %u >> %s\n", op[3], (op[3]-op[2]), strlen(op[3]), op[3]);
printf("TMP String: mem:0x%04X >> %s\n", tmp_string, tmp_string);
op[29] = "dolor sit amet, consectetur adipiscing elit";
printf("mem:0x%04X >> %u - %u >> %s\n\n\n", op[29], (op[29]-op[3]), strlen(op[29]), op[29]);
/* print mem layout */
for(int i = 0; i < 30; i++) {
printf("mem:0x%04X >> op[%u]\n", op[i], i);
}
return 0;
}