Stack around the variable 'st' was corupted

65 views Asked by At

This is my code to bind a text file content to a linked list in C, the read job is ok but its made an error in fclose(f), Stack around the variable 'st' was corrupted. I don't understand it, how can I fix it?

#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);
}

Update 1: Sorry, I must do it in C, but I use Visual C++, the final environment is C data file, 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

There are 2 answers

1
Some programmer dude On

You use fscanf to read the strings into an array containing 8 characters, which means you can read string having 7 characters at most because the last character must be the special string-termination character '\0'.

However, in the input you have e.g. the string

FESTIVAL

which is exactly 8 characters, but needs 9 characters including the terminator. This will cause fscanf to write beyond the bounds of the array st.

What's worse is that you then copy this 9-character data into an array of only 7 characters, once again writing out of bounds.

Writing out of bounds of an array leads to undefined behavior, and makes your whole program ill-formed.

0
James Kanze On

The most obvious problem: you're reading into a buffer of 8 char, but some of your data requires 9 (don't forget the trailing '\0'); you then strcpy this into a buffer of 7 char. For the input you give, you need buffers of at least 9 characters. You also want to provide a width argument in the format of fscanf, in order to avoid overwriting the buffer regardless of the input. (In fact, you probably want to use fgets, to read line by line, with a very large buffer, and then check that 1) you've actually read to the end of the line (the last character should be a '\n'), and 2) that the word in the line has at most one less characters than the size of your buffer.

(Obviously, this would all be significantly simpler in C++.)