You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免C语言中的Stack Smashing Detected?代码问题排查求助

解决Luhn算法C程序中的“Stack Smashing Detected”错误

“Stack Smashing Detected”是因为代码数组越界访问破坏了栈内存结构,触发了GCC的栈保护机制。下面是具体问题分析和修复方案:

问题根源

  1. 数组arr越界
    你定义了int arr[8],合法下标范围是0到7,但x初始值设为1,循环8次后x会递增到8,最后一次赋值arr[8] = d会访问数组边界外的内存,直接破坏栈上的其他数据,触发栈溢出检测。

  2. pow函数的精度问题
    用pow(y,z)计算10的幂会返回double类型,浮点数的精度误差可能导致计算出的除数不准确,比如pow(10,15)可能不是精确的1000000000000000,进而导致提取的数字出错。

  3. 数据类型溢出
    long类型在32位系统中最大值是2147483647,而16位信用卡号(比如4111111111111111)已经超过这个范围,card变量会溢出,导致输入的卡号被截断。

修复方案

1. 修复数组越界

把x的初始值改为0,确保数组下标始终在0-7范围内:

int x = 0; // 从0开始
for(int i = 0; i < 8; i++)
{
    // ... 其他代码
    arr[x] = d;
    x++;
}

2. 用整数运算替代pow

用一个整数变量保存当前除数,避免浮点精度问题:

unsigned long long divisor = 1000000000000000ULL; // 10^15
for(int i = 0; i < 8; i++)
{
    long long digit_part = card / divisor;
    int d = digit_part % 10; // 直接取最后一位
    arr[x] = d;
    x++;
    divisor /= 100; // 每次除以100,跳到下一个隔位数字
}

3. 更换合适的数据类型

把card改为unsigned long long,对应scanf格式符%llu:

unsigned long long card;
do
{
    printf("Enter the card number: ");
    scanf("%llu", &card);
} while (card < 1000000000000000ULL); // 用ULL后缀确保是无符号长整型常量

4. 完善Luhn算法逻辑

当前代码只计算了乘2后的数字和,还需要加上未被乘2的数字的和,且乘2后若为两位数,需拆成个位+十位再求和,最后判断总和是否模10为0:

// 计算未乘2的数字之和
int sum_other = 0;
unsigned long long temp_card = card;
for(int i = 0; i < 8; i++)
{
    sum_other += temp_card % 10;
    temp_card /= 100;
}

// 计算乘2后的数字之和(拆分两位数)
int sum_double = 0;
for(int j = 0; j < 8; j++)
{
    int doubled = arr[j] * 2;
    sum_double += (doubled / 10) + (doubled % 10);
}

int total_sum = sum_other + sum_double;
if (total_sum % 10 == 0)
{
    printf("This checks out, boss.\n");
}
else
{
    printf("Security will escort you out of the building big man.\n");
}

完整修复后的代码

#include <stdio.h>

int main(void) {
    unsigned long long card;
    do
    {
        printf("Enter the card number: ");
        scanf("%llu", &card);
    } while (card < 1000000000000000ULL);

    int arr[8];
    int x = 0;
    unsigned long long divisor = 1000000000000000ULL;

    for(int i = 0; i < 8; i++)
    {
        long long digit_part = card / divisor;
        int d = digit_part % 10;
        arr[x] = d;
        x++;
        divisor /= 100;
    }

    // 计算未乘2的数字之和
    int sum_other = 0;
    unsigned long long temp_card = card;
    for(int i = 0; i < 8; i++)
    {
        sum_other += temp_card % 10;
        temp_card /= 100;
    }

    // 计算乘2后的数字之和(拆分两位数)
    int sum_double = 0;
    for(int j = 0; j < 8; j++)
    {
        int doubled = arr[j] * 2;
        sum_double += (doubled / 10) + (doubled % 10);
    }

    int total_sum = sum_other + sum_double;
    if (total_sum % 10 == 0)
    {
        printf("This checks out, boss.\n");
    }
    else
    {
        printf("Security will escort you out of the building big man.\n");
    }

    return 0;
}

内容的提问来源于stack exchange,提问作者Vihaan Kaustuv

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 11:08:16