以下对象存储在内存中的什么位置? #包括 #包括 #包括 #定义文本“祝您这次考试好运” int main(){ char*cPtr=(char*)malloc(sizeof(TEXT)); strncpy(cPtr,TEXT,sizeof(TEXT)); printf(“%s\n”,cPtr); 免费(cPtr); 返回(退出成功); } 变量cPtr的内存cPtr cPtr指向的地址 malloc()的代码 malloc()调用以移动 运行此程序的进程
我认为:以下对象存储在内存中的什么位置? #包括 #包括 #包括 #定义文本“祝您这次考试好运” int main(){ char*cPtr=(char*)malloc(sizeof(TEXT)); strncpy(cPtr,TEXT,sizeof(TEXT)); printf(“%s\n”,cPtr); 免费(cPtr); 返回(退出成功); } 变量cPtr的内存cPtr cPtr指向的地址 malloc()的代码 malloc()调用以移动 运行此程序的进程,c,C,我认为: 堆 堆叠 数据段 共享库内存 正确吗? 堆叠 堆 资料 共享库 我会这样回答这个问题 char*cPtr=NULL在堆栈上声明一个char*,并将其分配给point to NULL,在您的实例中,malloc()将其分配给point to heap memory,但cPtr变量本身在堆栈上 Malloc分配堆内存 文本字符串位于数据段中,sizeof(“文本字符串”)将作为数据段中地址的一个地址进行处理。我想你的问题是指“malloc参数的代码” 您的代码没有定义函数malloc,因此
char*cPtr=NULL
在堆栈上声明一个char*,并将其分配给point to NULL,在您的实例中,malloc()将其分配给point to heap memory,但cPtr变量本身在堆栈上char*cPtr=NULL
在堆栈上声明一个char*,并将其分配给point to NULL,在您的实例中,malloc()将其分配给point to heap memory,但cPtr变量本身在堆栈上我可能在一个或多个答案上错了,但这是我的理解。如果有人能告诉我哪里错了,我会更正答案。唯一正确的答案是,无论编译器想在哪里。这可能不是您想要的答案,所以让我们来看看一个合理的编译器可能会选择什么
cPtr
可能根本不会存储在内存中。它可以放在寄存器中(指针几乎总是放在CPU寄存器中),并且您从不获取它的地址,因此它可能位于一个或多个寄存器中。它可以写入堆栈,然后读回以在strncpy
和printf
调用中保留其值,或者可以以其他方式保留其值。(请注意,编译器不需要在调用free
后保留其值,因为您将不再使用它。)malloc
几乎总是返回一个堆指针,因为这是分配动态内存最容易的地方,如果不是唯一可能的位置的话。因此,缓冲区将位于堆中malloc
,在这种情况下,它将驻留在共享库代码中,或者它可能只是内联函数的全部或部分,在这种情况下,它的部分或全部可能驻留在程序的代码中sbrk
。因此,此代码将驻留在操作系统的内核代码中“祝您在这个测试中好运”
,我认为讨论这个字符串也是值得的。此字符串出现在三种上下文中:
- 作为宏替换(通过
),它在编译之前由预处理器处理,因此在最终输出中根本不去任何地方李>#define
- 作为
函数的一个参数,在这种情况下,它作为只读数据包括在程序的可执行代码中,或者与程序的可执行代码一起包含在专门为只读数据制作的单独部分中李>strncpy
- 作为
运算符的参数。这是三个案例中最有趣的一个。从技术上讲,它应该与前一个相等;但是,许多编译器可以静态计算常量字符串的大小(毕竟这非常简单),因此它们可以用普通的sizeof
替换23
,并避免完全发出字符串(对于这种情况)sizeof(TEXT)
可能根本不会存储在内存中。它可以放在寄存器中(指针几乎总是放在CPU寄存器中),并且您从不获取它的地址,因此它可能位于一个或多个寄存器中。它可以写入堆栈,然后读回以在cPtr
和strncpy
调用中保留其值,或者可以以其他方式保留其值。(请注意,编译器不需要在调用printf
后保留其值,因为您将不再使用它。)free
几乎总是返回一个堆指针,因为这是分配动态内存最容易的地方,如果不是唯一可能的位置的话。因此,缓冲区将位于堆中malloc
- 编译器在这里有一个选择。它可能引用某个共享库中链接的
,在这种情况下,它将驻留在共享库代码中,或者它可能只是内联一个malloc
#include <stdlib.h> #include <stdio.h> #include <string.h> #define TEXT "Good luck on this test" int main () { char* cPtr = (char*)malloc(sizeof(TEXT)); strncpy(cPtr,TEXT,sizeof(TEXT)); printf("%s\n",cPtr); free(cPtr); return(EXIT_SUCCESS); }
main: # @main push rbx mov edi, 23 call malloc mov rbx, rax ; at this point, rbx roughly corresponds to cPtr ; it's also still in rax but rax is overwritten by the next operation movabs rax, 32777976875610985 ; btw this weird number is a piece of string mov qword ptr [rbx + 15], rax movups xmm0, xmmword ptr [rip + .L.str] movups xmmword ptr [rbx], xmm0 ; rbx (cPtr) is copied to rdi in order to give it to puts as argument mov rdi, rbx call puts mov rdi, rbx call free xor eax, eax pop rbx ret .L.str: .asciz "Good luck on this test"
- 唯一正确的答案是,无论编译器想在哪里。这可能不是您想要的答案,所以让我们来看看一个合理的编译器可能会选择什么