变量'state'周围的堆栈已损坏

时间:2014-11-11 14:05:18

标签: c++ pointers file-read

这是我的代码,用于将文本文件内容绑定到C中的链接列表,读取作业没问题,但是在fclose(f)中出现错误,变量'st'周围的堆栈已损坏。我不明白,我该如何解决?

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <iostream>
using namespace std;


struct Nut
{
    char Tu[7];
    Nut * Tiep;
};


Nut TD[26];
Nut *first;

void AddFirst(Nut *q, Nut *&first)
{
    Nut *p;
    p = new Nut;
    if (first == NULL)
    {
        first = q;
        return;
    }
    for (p = first; p->Tiep != NULL; p = p->Tiep)
        p->Tiep = q;
}

void ReadData(Nut *ds[], int &n)
{
    n = 0;
    char old = '0';
    FILE *f;
    Nut *Tam;
    Nut *Tu;
    f = fopen("TD.txt", "r");

    int dem = -1;
    if (f == NULL)
        cout << "File rong !!!";
    else
    {
        while (!feof(f) == 1)
        {
            char st[8] = "";
            fscanf(f, "%s", st);
            Tam = new Nut();
            strcpy(Tam->Tu, st);
            char c = st[0];
            if (c != old){
                dem++;
                ds[dem] = new Nut();
                n++;
            }
            AddFirst(Tam, ds[dem]);
        }
    }
    fclose(f);
}

更新1: 对不起,我必须在C中做,但我使用的是Visual C ++,最终的环境是C 数据文件,td.txt

ACCEPT
ADULT
APART
AUGUST
BACK
BAD
BOY
BREAK
CAT
CHEF
CHICKEN
COWBOY
CRY
DAD
DESIGN
DIE
DRAW
EAT
EMPTY
ERROR
EXPLORE
FAN
FELL
FESTIVAL
FULL
GAS
GIVE
GRAPHIC

2 个答案:

答案 0 :(得分:1)

使用fscanf将字符串读入包含8个字符的数组,这意味着您可以读取最多包含7个字符的字符串,因为最后一个字符必须是特殊的字符串终止字符'\0'

然而,在输入中你有例如字符串

FESTIVAL

正好是8个字符,但需要 9 个字符,包括终结符。这将导致fscanf超出数组st的范围。

更糟糕的是,您将这个9个字符的数据复制到一个只有7个字符的数组中,再次写出界限。

写出超出数组的范围会导致undefined behavior,并使整个程序形成错误。

答案 1 :(得分:0)

最明显的问题是:你正在阅读缓冲区 8 char,但你的一些数据需要9(不要忘记尾随 '\0');然后将strcpy放入7 char的缓冲区中。为了 你输入的输入,你需要至少9个字符的缓冲区。你也是 想要以fscanf的格式提供宽度参数,以便 无论输入如何,都要避免覆盖缓冲区。 (事实上​​,你 可能想要使用fgets逐行读取,非常大 缓冲区,然后检查1)你实际读到的结尾了 line(最后一个字符应该是'\n'),以及2)单词in 该行的字符数最多比缓冲区的大小少一个。

(显然,这在C ++中会非常简单。)