这是用C写的乘法还是堆栈设置中的指针

这是用C写的乘法还是堆栈设置中的指针,c,pointers,stack,C,Pointers,Stack,我试图理解这个堆栈的实现是如何工作的,我遇到了这段代码 while(x-- >= 0){ token_size = (strlen(argv[x])+1)*sizeof(char); *esp = *esp - token_size; arr[x] = (uint32_t *)*esp; memcpy(*esp, argv[x], strlen(argv[x])+1); } 首先,当我们将参数推送到堆栈时,为什么要减

我试图理解这个堆栈的实现是如何工作的,我遇到了这段代码

while(x-- >= 0){
        token_size = (strlen(argv[x])+1)*sizeof(char);
        *esp = *esp - token_size;
        arr[x] = (uint32_t *)*esp;
        memcpy(*esp, argv[x], strlen(argv[x])+1);
    }
首先,当我们将参数推送到堆栈时,为什么要减少堆栈指针?我的印象是,我们将参数添加到堆栈的末尾,并从堆栈的前端获取参数,所以我们肯定会增加堆栈指针以添加到堆栈的末尾?如果我错了,请纠正我(几乎肯定是这样)

回到标题的主题,在while循环的第一部分中,字符串argv[x]的大小添加了+1,我不确定为什么会出现这种情况,这是将字符串大小乘以
sizeof(char)
还是一个指针


感谢您的任何解释(无论大小),提前谢谢

在实践中,堆栈可以向上生长,也可以向下生长。关于计算机体系结构,有一些深刻的历史导致堆栈向下增长,包括今天的x86处理器,您可能每天都在使用。只要堆栈使用一致,向下增长就不是功能问题(尽管它会带来一些复杂的安全问题)

关于表达式
(strlen(argv[x])+1)*sizeof(char)

我们添加+1为空终止符腾出空间。在C语言中,字符串只是连续的非空字符,后跟一个空字符来标记结束
strlen
不计算长度的空值(例如
strlen(“Hello”)
为5,而计算空值时存储空值所需的内存为6个字符)


*
是一个乘法运算——它是一个在左右两侧都有一个操作数的二进制运算符。星号用于在一元上下文中执行指针间接寻址(例如
*a=5
foo(*b,*c)

您是否尝试过运行它以查看代码在做什么?当
x
0
时,您进入循环时,将更新
-1
x
…可能的UB in
argv[-1]
arr[-1]
,…您好,谢谢您回答我的问题,如果*在这种情况下是多应用程序,那么大小(字符)始终为1,那么为什么此实现将字符串长度互放1,因为结果将与互放不存在的结果相同。我应该更清楚地回答我的第一个问题。顺便说一句,在这种情况下,它是PintOS中的堆栈实现,包含的代码是从setup_stack函数中提取的,该函数是我们推送参数的地方对于堆栈,堆栈遵循后进先出原则,因此,例如,如果堆栈是数组堆栈[],则堆栈[0]如果堆栈指针指向堆栈的最后一个部分,那么为什么当我们推到堆栈时,我们会将堆栈指针放在更靠近堆栈底部的位置?或者减少堆栈指针使其远离堆栈[0]?@meme只要在弹出时增加堆栈指针,则在按下时减少堆栈指针是可以的。乘法实际上是为了保持一致性,因为您确实要乘以1——这表明您正在为字符分配存储。@meme
*sizeof(char)
是。由于
strlen()
的使用,分配已经与
char
相关。Re“只要堆栈一直使用,向下增长就不是问题”:实际上,这是一个重要的区别。向下增长意味着缓冲区溢出堆栈上较早的损坏数据。这包括返回地址,允许攻击者影响程序控制流。如果堆栈被反转,缓冲区溢出造成破坏的机会将减少。