注册 登录
编程论坛 C语言论坛

栈溢出问题

飞天大烧卖 发布于 2020-04-09 10:36, 2127 次点击

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main(void)
{
    FILE  *fp;
    char a[2][80]={0},i=0;
    if((fp = fopen("a.txt", "w")) == NULL){
        printf("Can't Open File!");
        exit(0);
    }
    a[0][0]='c';
    a[1][0]='b';
     if(!feof(fp))
     {
           for(i=0;i<2;i++)
           {
             fprintf(fp,"%s ",a[i][0]);//我知道表示字符串要用数组名即a[i],问题是为什么用
                           // a[i][0]编译器不报错,运行时怎么溢出的啊?怎么把这过程搞清楚啊?
           }
     }
    fclose(fp);   
}

调试到 fprintf(fp,"%s ",a[i][0]);这一步就如图所示,百度了一下是栈溢出
  unhandled exception in 新建文本文档.exe:0xc00000005:Access Violation.
5 回复
#2
rjsp2020-04-09 11:08
我知道表示字符串要用数组名即a[i], a[i][0]编译器不报错
因为 fprintf 的原型是 int fprintf( FILE *stream, const char *format, ... );
所以你传什么类型的变量都是合乎语法的,你得自己去保证正确。
当然,现在的编译器能在编译时发现这个错误。

运行时怎么溢出的啊?
fprintf(fp,"%s ",a[i][0]); 就等同于 fprintf(fp,"%s ", 'c' );
不出错才奇怪呐
#3
lin51616782020-04-09 11:11
fprintf 是变参函数
他只知道第一个参数的类型
一共有多少个参数 其他参数是什么类型都是不清楚的
所以编译器没报错
现代编译器可以检查出类型不匹配 可能会有警告

运行时错误的因为 %s 执行方式是
从指定的地址开始读取数据 遇到0停止
你给出一个char
%s就把这个char当成地址
a[0][0]的值是 'c'也就是 0x00000063
%s 会从0x00000063这个地址开始读取数据直到遇到0字节
这个地址不允许读就出错了
#4
fulltimelink2020-04-09 11:12
fprintf(fp, "%s ", &a[i][0]);
#5
forever742020-04-09 11:20
这些问题的理论解释都可以存在,但习惯上我一般都表示你完整地学完C语言以后就明白了,因为解释它需要引用相对后面的知识。

事实上很多问题不建议初学者深挖,凡事须知适可而止,从应用上看,更重要的是知道怎样写是正确的,而你已经知道了。
知道毒品有害不要去碰就好了,难道还要深入学习毒品的分子生物学作用机理?
吾生也有涯,而知也无涯。以有涯随无涯,殆已!
#6
飞天大烧卖2020-04-09 12:01
谢谢
1