在C中使用数组的奇怪行为[重复]

zxlwwiss  于 2023-06-21  发布在  其他
关注(0)|答案(1)|浏览(85)

此问题已在此处有答案

How dangerous is it to access an array out of bounds?(12个回答)
14天前关闭
我正在学习C语言,特别是指针和内存访问。我写了这个简单的程序来计算字符串中的字符数,但“问题”是它在应该给予我错误的时候工作。
更具体地说,即使我输入的字符比预期的多(5),函数mylen * 仍然 * 能够正确地计算字符数。我也尝试了非常大的数字(>50)。为什么?

#include <stdio.h>    

int mylen(char*);    

int main(){    
    char mystring[5];    
    printf("Enter a string: ");    
    scanf("%s", &mystring);    
    int lenght = mylen(mystring);    
    printf("The string is %d chars long", lenght);    
    return 0;
}    
int mylen (char *ptr) {    
    int len;    
    len = 0;    
    char t;    
    while (*ptr != '\0'){    
        ptr++;    
        len ++;    
    }    
    return len;    
}

P.S.我知道有更有效和安全的方法来读取字符串,比如getline(),但我对这个特定的问题很好奇。感谢您的任何澄清。

ndasle7k

ndasle7k1#

就C而言,这是未定义的行为。有时它可能会产生你所期望的结果,有时可能不会。它依赖于编译器实现,在技术上与C标准无关。
如果你问“当我提供一个长度为10的字符串时,它仍然正确地计算出字符串长度为10,为什么?”“那是因为你很可能还在数组的边界之外写字。你只是覆盖了相邻的数据,这是非常危险的。但在您的用例中,您仍然可能将X字节写入堆栈。你只是覆盖了5字节缓冲区旁边的X - 5字节(这里假设char = 1字节,这是通常的做法,但技术上它依赖于系统)。
尝试给出一个很长的字符串,例如100个或更多字符。您可能会遇到一个分段错误,这是由于写入超出堆栈帧并损坏返回地址。或者,您可能会覆盖堆栈金丝雀并产生“检测到堆栈粉碎”错误。

相关问题