gpt4 book ai didi

c - 堆栈问题 : a pointer points to a variable inside function(stack)

转载 作者:太空宇宙 更新时间:2023-11-04 03:09:43 24 4
gpt4 key购买 nike

在函数中定义的变量是在堆栈上创建的。然后,当函数调用完成时,该变量由于堆栈输入/输出而消失。

下面的代码传递了一个数据结构

typedef struct
{
test_out_t output;
test_in_t input;
} message_t;

typedef struct
{
uint8_t len;
uint8_t* data_out;
} test_out_t;

typedef struct
{
uint8_t len;
uint8_t* data_in;
} test_in_t;

函数调用是 void test(message_t *msg);

在函数中,我定义了一个数组,并将指针指向这个数组(内存位置)。但是,当函数调用完成时,我希望指针指向值变为未确定/零,因为堆栈变量已经消失。

但是,如果我在函数内部调用 printf(),它仍然具有堆栈变量的值。

使用以下代码,msg.output.data_out 包含在函数中创建的数组的值。

如果把test()里面的printf注释掉。 msg.output.data_out 全部为零。

    #include <stdio.h>
#include <stdint.h>
#include <string.h>

#define DATA_SIZE (8)


typedef struct
{
uint8_t len;
uint8_t* data_out;
} test_out_t;

typedef struct
{
uint8_t len;
uint8_t* data_in;
} test_in_t;

typedef struct
{
test_out_t output;
test_in_t input;
} message_t;



void test(message_t *msg);



void test(message_t *msg)
{
uint8_t stackdata[DATA_SIZE];
memset(stackdata, 0, DATA_SIZE);
for (int i=0; i<DATA_SIZE; i++)
stackdata[i] = i+1;

msg->output.len = DATA_SIZE;
msg->output.data_out = stackdata;

uint8_t data2[msg->input.len];
memcpy(&data2, msg->input.data_in, msg->input.len);

for (int i=0; i<msg->input.len; i++)
printf("0x%X\t", data2[i]);
}

int main(void) {

message_t msg;
uint32_t data2 = 0x12345678;
msg.input.len = 4;
msg.input.data_in = (uint8_t*)&data2;


test(&msg);
printf("\n");
for (int i=0; i<msg.output.len; i++)
printf("0x%X\t", msg.output.data_out[i]);
return 0;
}

我假设一些与 printf() 相关的东西

顺便说一句,我正在使用在线编译器来运行代码。

https://repl.it/languages/c

最佳答案

C 的规则说,当一个对象的生命周期结束1 时,我们无法对此做出任何保证。因此,您不能正确使用它,因为您无法保证它。规则并没有说任何东西都会删除或随机化对象。

在典型的实现中,当函数返回时,堆栈指针会更改为指向新的堆栈顶部。没有任何额外的工作来删除堆栈上的任何数据。所以它仍然存在,直到发生其他事情。

这并不意味着您可以可靠地使用堆栈上的空间。有多种因素可以改变数据或改变您对数据的使用:

  • 其他例程调用将使用堆栈。
  • 当前例程中的其他操作可能会使用堆栈。
  • 信号可能会导致堆栈被使用。
  • 如果编译器发现您对该对象的使用不受支持,其优化可能会以意想不到的方式改变您的程序。

脚注

1 “对象的生命周期是程序执行的一部分,在此期间保证为其保留存储空间”(C 2018 6.2.4 1)。对于函数中定义的常规对象,它们的生命周期在函数执行结束时结束(通常是因为函数返回,但也可能是因为执行了 longjmp 或程序正在终止)。因此,当生命周期结束时,这意味着存储不再保证保留。存储仍然存在。没有什么可以保证改变它。所有的变化是,当函数正在执行时,您可以保证为该对象保留存储空间,并且在函数结束后,保证就消失了。

关于c - 堆栈问题 : a pointer points to a variable inside function(stack),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57717984/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com