c - 为指针及其数据分配的内存在哪里?

标签 c string pointers memory memory-management

我的问题是我是否有一些功能

void func1(){
    char * s = "hello";
    char * c;
    int b;
    c = (char *) malloc(15);
    strcpy(c,s);
}

我认为 s 指针是在堆栈上分配的,但是数据“hello”存储在程序的数据段中吗?至于 c 和 b,它们是单元化的,因为“c = 一些内存地址”并且它还没有一个,这是如何工作的?而且 b 也没有内容,所以它不能存储在堆栈中? 然后,当我们使用 malloc 在堆上为 c 分配内存时,c 现在有一些内存地址,这个未初始化的 c 变量是如何为堆上的字符串的第一个字节的地址指定的?

最佳答案

我们需要考虑一个变量有什么内存位置以及它的内容是什么。请记住这一点。

对于一个 int,变量有一个内存地址和一个数字作为它的内容。

对于 char 指针,变量有一个内存地址,它的内容是一个指向字符串的指针——实际的字符串数据在另一个内存位置。

要理解这一点,我们需要考虑两件事:

(1) the memory layout of a program
(2) the memory layout of a function when it's been called

Program layout [typical]. Lower memory address to higher memory address:

code segment -- where instructions go:
  ...
  machine instructions for func1
  ...
data segment -- where initialized global variables and constants go:
  ...
  int myglobal_inited = 23;
  ...
  "hello"
  ...
bss segment -- for unitialized globals:
  ...
  int myglobal_tbd;
  ...
heap segment -- where malloc data is stored (grows upward towards higher memory
addresses):
  ...
stack segment -- starts at top memory address and grows downward toward end
of heap

Now here's a stack frame for a function. It will be within the stack segment somewhere. Note, this is higher memory address to lower:

function arguments [if any]:
  arg2
  arg1
  arg0
function's return address [where it will go when it returns]
function's stack/local variables:
  char *s
  char *c
  int b
  char buf[20]

Note that I've added a "buf". If we changed func1 to return a string pointer (e.g. "char *func1(arg0,arg1,arg2)" and we added "strcpy(buf,c)" or "strcpy(buf,c)" buf would be usable by func1. func1 could return either c or s, but not buf.

That's because with "c" the data is stored in the data segment and persists after func1 returns. Likewise, s can be returned because the data is in the heap segment.

But, buf would not work (e.g. return buf) because the data is stored in func1's stack frame and that is popped off the stack when func1 returns [meaning it would appear as garbage to caller]. In other words, data in the stack frame of a given function is available to it and any function that it may call [and so on ...]. But, this stack frame is not available to a caller of that function. That is, the stack frame data only "persists" for the lifetime of the called function.

Here's the fully adjusted sample program:

int myglobal_initialized = 23;
int myglobal_tbd;

char *
func1(int arg0,int arg1,int arg2)
{
    char *s = "hello";
    char *c;
    int b;
    char buf[20];
    char *ret;

    c = malloc(15);
    strcpy(c,s);

    strcpy(buf,s);

    // ret can be c, s, but _not_ buf
    ret = ...;

    return ret;
}

关于c - 为指针及其数据分配的内存在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32936349/

相关文章:

c++ - 混合来自不同编译器的 C++ 代码

c++ - 如何找到我的阵列使用的内存

C++:对象 vector 与指向新对象的指针 vector ?

c - 如何在 child 完成之前杀死父进程?

c++ - 指向数组重叠数组末端的指针

Python 替换列表中的字符

c - C中的阅读空间

连续字符串

C++:无法使用类型为 'char**' 的右值初始化类型为 'char*[x]' 的变量

c - 套接字,为什么 ip 以整数格式发送?