加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

将变量保存在内存中,C

发布时间:2020-12-16 09:27:02 所属栏目:百科 来源:网络整理
导读:今天出现了一些奇怪的东西.当我想用旧的方式在C(C)中保存一些字符串时,不使用字符串头,我只是创建数组并将该字符串存储到其中.但是,我读到在本地功能范围内C中的任何变量定义最终都会将这些值推送到堆栈中. 因此,字符串实际上比需要的大2倍.因为首先,推送指
今天出现了一些奇怪的东西.当我想用旧的方式在C(C)中保存一些字符串时,不使用字符串头,我只是创建数组并将该字符串存储到其中.但是,我读到在本地功能范围内C中的任何变量定义最终都会将这些值推送到堆栈中.

因此,字符串实际上比需要的大2倍.因为首先,推送指令位于存储器中,但是当它们被执行(推入堆栈)时,创建了字符串的另一个“副本”.首先是推送指令,而不是堆栈空间用于一个字符串.

那么,为什么会这样呢?为什么编译器只是将字符串(或其他变量)添加到程序中而不是在执行时再次创建它们?是的,我知道你不能只在程序块中有一些数据,但它可能只是附加到程序的末尾,之前有一些跳转指令.而且,我们只是指出这些数据?因为它们在执行程序时存储在RAM中.

谢谢.

解决方法

如果你有:

extern void some_function(char * s,int l);

void do_it(void) {
     char str[] = "I'm doing it!";
     some_function(str,sizeof(str) );
}

这将变成类似的东西(在psudo asm中为组合处理器):

.data
local .do_it.str       ; The contents of str are stored in a static variable
.text   ; text is where code lives within the executable or object file
do_it:
    subtract (sizeof(str)) from stack_pointer        ; This reserves the space for str,sizeof(str)
                                                     ; and a pointer to str on the stack

    copy (sizeof(str)) bytes from .do_it.str to [stack_pointer+0]   ; this loads the local variable
                                               ; using to the memory at the top of the stack
                                               ; This copy can be a function call or inline code.

    push sizeof(str)         ; push second argument first
    push stack_pointer+4     ; assuming that we have 4 byte integers,; this is the memory just on the other side of where we pushed
                             ; sizeof(str),which is where str[0] ended up

    call some_function

    add (sizeof(str)+8) to stack_pointer          ; reclaim the memory used by str,sizeof(str),; and the pointer to str from the stack
    return

从中您可以看出,关于如何创建局部变量str的假设并不完全正确,但这仍然不一定有效.

如果你这样做了

void do_it(void) {
     static str[] = "I'm doing it!";

然后编译器不会为堆栈保留堆栈上的空间,然后将其复制到堆栈中.如果some_function要改变str的内容,则对do_it的下一个(或并发)调用(在同一个进程中)将使用str的更改版本.

如果some_function被声明为:

extern void some_function(const char * s,int l);

然后,由于编译器可以看到在do_it中没有更改str的操作,即使str未被声明为静态,它也可以在堆栈上不生成str的本地副本.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读