【问题标题】:stack smashing on string compare? [duplicate]字符串比较时堆栈粉碎? [复制]
【发布时间】:2021-06-03 19:58:46
【问题描述】:

我正在编写一个基本的qsort 来对字符串数组进行排序。到目前为止我所拥有的是:

int scmp(const void *p1, const void *p2)
{
    const char* s1 = p1;
    const char* s2 = p2;
    // ...
}

int main(void)
{
    char* strings[] = {"Onus", "deacon", "Alex", "zebra"};
    qsort(strings, sizeof(strings), sizeof(*strings), scmp);
}

请注意,sizeof(strings) 上面给了我 32(4 个指针),而我想要的是 sizeof(strings)/sizeof(*strings)。这解决了这个问题,但我很好奇“堆栈粉碎”是什么意思以及它是如何发生的?

【问题讨论】:

  • 堆栈粉碎只是意味着代码正在写入它不应该写入的堆栈部分。发生这种情况是因为qsort 写入了您给它进行排序的数组。既然你告诉它,数组中的条目比实际要多,它会写入它不应该写入的地方。

标签: c


【解决方案1】:

strings 指针数组在堆栈上分配。有了你的错误,你“撒谎”到 qsort 并告诉它有 32 个 char* 需要排序,而不是 4 个。所以它在分配的数组之外运行并访问你无权访问的内存。

然后可能发生的是未定义的行为。访问无效存储可能会出现“段错误”(SIGSEGV)或“访问冲突”。你可以默默地破坏堆栈数据,导致非常奇怪的错误。在这种情况下,您会遇到“堆栈粉碎”,这仅意味着检测到堆栈损坏。当您覆盖“堆栈金丝雀”时会发生这种情况1),这是在堆栈上设置的一个固定值,主要用于警告堆栈溢出。


1) 以煤矿中使用的金丝雀鸟的类比命名 - 如果一氧化碳中毒,金丝雀会首先昏倒,因此矿工会注意到并使其安全。

【讨论】:

  • (在某个时候,我提议将 Stack Overflow“元上的小酒馆”聊天命名为 Stack Canary Twitter,但这是一个如此复杂的书呆子笑话,没有人知道......)跨度>
  • @lunda -- 谢谢。 “stack canary”是 GCC 编译器特有的,还是 C 标准的一部分?
  • @David542 C 标准甚至没有提及或要求堆栈。这是一个技巧,特定编译器可以设置为在 main() 启动之前执行的 C 运行时的一部分。在嵌入式系统上,您可以通过映射堆栈自己创建类似的东西,以便它溢出到内存中,数据访问读取到异常/中断。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-26
  • 1970-01-01
相关资源
最近更新 更多