#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);
}
cPtr
的内存?cPtr
指向的地址?malloc()
的代码?malloc()
调用以移动 brk指针的代码
正在运行此程序?我认为是
对吗?
答案 0 :(得分:3)
唯一的正确答案是,无论编译器感觉如何。那可能不是您想要的答案,所以让我们研究一下合理的编译器可能会选择什么。
cPtr
可能根本不会存储在内存中。它适合一个寄存器(指针几乎总是适合CPU寄存器),并且您永远不会占用其地址,因此它可能位于一个或多个寄存器中。可以将其写入堆栈,然后回读以在strncpy
和printf
调用中保留其值,或者可以通过其他方式保留其值。 (请注意,编译器无需在free
调用后保留其值,因为您再也不会使用它了。)malloc
几乎总是返回堆指针,因为在那儿分配动态内存是最容易的,即使不是唯一可能的位置。因此缓冲区将在堆中。malloc
,在这种情况下,它将驻留在共享库代码中,或者可能仅内联函数的全部或一部分,在这种情况下,其一部分或全部可能驻留在您的库中。程序的代码。sbrk
处理的。因此,这些代码将驻留在操作系统的内核代码中。编辑:由于有人提到了静态字符串"Good luck on this test"
,所以我认为讨论一个静态字符串也是值得的。该字符串出现在三个上下文中:
#define
),它在编译之前由预处理器处理,因此在最终输出中根本没有任何作用; strncpy
函数的自变量,在这种情况下,它与程序的可执行代码一起包含在只读数据中,或者包含在专门用于读取的单独部分中-仅数据; sizeof
运算符的自变量。这是三个中最有趣的情况。从技术上讲,它应该等效于上一个;但是,许多编译器可以静态计算常量字符串的大小(毕竟非常简单),因此他们可以将sizeof(TEXT)
替换为普通的23
并避免完全发出字符串(对于这种情况) )。答案 1 :(得分:3)
实际上这是一个主要问题,因为它假定所有内容都将保存在内存中。
局部变量以及没有名称的临时值仅在必要时放在堆栈中。 。有不同的原因可能需要这样做,例如:
上述情况很可能都不适用(最后一项绝对不适用,地址也没有使用),因此我们应该期望cPtr
将整个生命周期都花在寄存器中。
在针对{64的x {3}}上进行测试,我们可能会得到如下代码:
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"
以GCC为目标的MIPS或ARM或PowerPC显示了类似的模式cPtr
不在堆栈中,而是在一个寄存器(或多个寄存器,取决于您的计数方式)中,尽管代码看起来很漂亮不同。
上面代码的一个有趣的细节是,虽然整个字符串确实出现在数据段(rodata)中,但它的一部分也作为该movabs
的直接操作数出现在代码段中。
答案 2 :(得分:-1)
这就是我要回答这个问题的方式。
char * cPtr = NULL;
在堆栈上声明一个char *并将其分配为指向NULL。在您的实例中,malloc()将其分配为指向堆内存,但是cPtr变量本身在堆栈上。
Malloc分配堆内存。
TEXT字符串位于数据段中,并且sizeof(“ TEXT STRING”)将作为对数据段中地址的operator处理。我认为您的问题意味着“ malloc参数的代码”
您的代码未定义函数malloc,因此由于您#include的其中一个库,它必须执行的所有操作。
我可能对其中一个或多个答案有误,但这是我的理解。如果有人可以告诉我我错了哪里,请改正答案。