0

After hours and hours of searching, I became desperate because I just fail to find uninitialized reads that I apparantly have, according to Valgrind and Dr. Memory, so I'll ask here for help. I used the Code Blocks' debugger and its variable watch, but all I saw there was everything going smoothly and as planned.

#define ADRESA "adressbook.txt"

struct Adress
{
    char name[31], lastname[31], email[48], major[10];
    int year;
};

int read(struct Adresa array[])
{
    char temp_line[121];
    int i = 0, j, c = 0;
    FILE* adressbookf = fopen(ADRESA, "r");
    if (adressbookf != NULL)
    {
        printf("File successfully loaded.\n")

        while (fgets(temp_line, 121, adressbookf) != NULL && strlen(temp_line) > 0)
        {
            j = 0;
            c = 0;
            while (temp_line[c] != ',' && c < strlen(temp_line))
            {
                array[i].name[j] = temp_line[c];
                ++j;
                ++c;
            }
            ++c;
            array[i].name[j] = '\0';
            j = 0;

            while (temp_line[c] != ',' && c < strlen(temp_line))
            {
                array[i].lastname[j] = temp_line[c];
                ++j;
                ++c;
            }

            ++c;
            array[i].lastname[j] = '\0';
            j = 0;

            while (temp_line[c] != ',' && c < strlen(temp_line))
            {
                array[i].email[j] = temp_line[c];
                ++j;
                ++c;
            }

            ++c;
            array[i].email[j] = '\0';
            j = 0;

            while (temp_line[c] != ',' && c < strlen(temp_line))
            {
                array[i].major[j] = temp_line[c];
                ++j;
                ++c;
            }

            ++c;
            array[i].year = temp_line[c] - 48;
            ++i;
        }
        fclose(adressbookf);
        return i;
    }
    else return 0;

}

int main()
{
    int number_of_elements = 0;
    struct Adress adressbook[1000];
    printf("Welcome.\n");
    number_of_elements = read(adressbook);

...

Apparently, the lines with error are 32, 43 and 54 (Conditional jump or move depends on uninitialised value(s)).

The file looks something like this:

name,lastname,nlastname1@x.com,EE,1

john,doe,jdoe1@x.com,AA,1

And it usually ends with a trailing line containing '\n' (but the file doesn't necessarily exists).

I have one more error in the program, but I'd have to copy the whole program here. I hope that one will be resolved with this.

If someone would willing to compile it and examine it that way, I'll be happy to post it.

Here's the error message from Valgrind:

Conditional jump or move depends on uninitialised value(s) at 0x4010F1: ucitaj (bs_test_2366.c:156) by 0x40192E: _main (bs_test_2366.c:255) by 0x4021EE: main (bs_test_2366.c:385)

Conditional jump or move depends on uninitialised value(s) at 0x4011AD: ucitaj (bs_test_2366.c:167) by 0x40192E: _main (bs_test_2366.c:255) by 0x4021EE: main (bs_test_2366.c:385)

Conditional jump or move depends on uninitialised value(s) at 0x401269: ucitaj (bs_test_2366.c:178) by 0x40192E: _main (bs_test_2366.c:255) by 0x4021EE: main (bs_test_2366.c:385)

Note that lines 156, 167 are 178 the first, second and the third

while (temp_line[c] != ',' && c < strlen(temp_line))

respectively. 255 is the line where the function is called, and 385 is outside of my program.

Bane Bojanić
  • 712
  • 1
  • 8
  • 20
  • If the debugger says "uninitialized variable" and gives you the exact line of the error,what more do you need? – bolov Jan 17 '15 at 14:36
  • This is the first time in my life getting in contact with a memory debugger such as Valgrind. With "fgets(temp_line, 121, adressbookf) != NULL && strlen(temp_line) > 0" in the outer while and with c < strlen(line) I basically abort reading when I reach the end of line or the file. I thought someone with more experience could read it somewhat easilly, because I just can't see where could I possibly touch something uninitialized in those lines. – Bane Bojanić Jan 17 '15 at 14:40
  • While I see various problems with your code - the main question is: Why are you not simply using fscanf or at least strtok(_r)? – Andreas Jan 17 '15 at 14:52
  • You should use `sizeof(temp_line)` instead of 121 – Basile Starynkevitch Jan 17 '15 at 14:56
  • Andreas; I thought this is simpler because of the trailing '\n' and the commas in the file. – Bane Bojanić Jan 17 '15 at 15:03
  • without a file it runs ok. Paste the file on pastebin and I will run the program. Post the link as a comment. – bolov Jan 17 '15 at 15:07
  • bolov: here's the complete program with the file at the end: http://pastebin.com/NdUtPfNQ – Bane Bojanić Jan 17 '15 at 15:09
  • it runs fine (the short version from the question) with the file. – bolov Jan 17 '15 at 15:15
  • can you compile the complete program? I don't see why would one work and the second would not. – Bane Bojanić Jan 17 '15 at 15:15
  • Probably not related to your problem, but in the nested conditions, you should probably use `temp_line[c] != '\0'`, rather than `c < strlen(temp_line)`. It's both more idiomatic, and a lot more efficient. (Most idiomatic, of course, would be to use pointers, rather than indices.) And your code is pure C; you should remove the C++ tag – James Kanze Jan 17 '15 at 15:16
  • the full program runs and then asks for some kind of input. On an unrelated note I just noticed that you copy to the fields of `Adress` without checking you don't step outside of the buffers. (e.g. you copy to the `email` filed and don't check you don't copy more than `48` characters. Also don't copy char by char. Use `strcpy` (but again make sure you don't overflow. – bolov Jan 17 '15 at 15:24
  • Perhaps this might be rewritten with fscanf or something? I tried parsing it with fscanf(adresarf, "%s[^,]", adresbook.name) but it wasn't a success. – Bane Bojanić Jan 17 '15 at 15:29
  • Bolov: well, if you have Valgrind or Dr Memory or something like that installed, you can easily recreate the error. – Bane Bojanić Jan 17 '15 at 15:29
  • I couldn't reproduce your error. As I said the program runs on my system. Beyond that I think it is not my job to check your homework. – bolov Jan 17 '15 at 15:33
  • Please make sure that your code compiles without warnings before posting it (unless the question is about failing to understand why the code doesn't compile). – August Karlstrom Jan 17 '15 at 15:44
  • Comments are not for extended discussion; this conversation has been [moved to chat](http://chat.stackoverflow.com/rooms/69029/discussion-on-question-by-bane-bojanic-debugger-says-i-have-uninitialized-variab). – Taryn Jan 17 '15 at 15:55

2 Answers2

1

I see a possible problem. In the first line you index with c before you check the range.

        while (temp_line[c] != ',' && c < strlen(temp_line))
        {
            array[i].name[j] = temp_line[c];
            ++j;
            ++c;
        }

try writing it like this:

        while (c < strlen(temp_line) && temp_line[c] != ',')
        {
            array[i].name[j] = temp_line[c];
            ++j;
            ++c;
        }
Gábor Angyal
  • 2,225
  • 17
  • 27
  • Oh, you noticed it well but unfortunately it didn't help. What confuses me is that c should never be >= than line length, because I used simple examples, but the debugger still crashes- – Bane Bojanić Jan 17 '15 at 14:47
  • On the contrary. If `c == strlen(temp_line) - 1` then you enter the while loop, `c` gets increased, becomes equal to `strlen(temp_line)` and at the check of the loop condition the index goes out of range. – Gábor Angyal Jan 17 '15 at 15:18
  • Is there a good way to rewrite this to just parse the text file with fscanf? – Bane Bojanić Jan 17 '15 at 15:21
  • Check out [this](http://stackoverflow.com/questions/5167625/splitting-a-c-stdstring-using-tokens-e-g) question. I beleive you can simplify your code using this. – Gábor Angyal Jan 17 '15 at 15:31
  • I need to do it in C. – Bane Bojanić Jan 17 '15 at 15:31
  • Sorry, my bad. Read this then: [http://stackoverflow.com/questions/9210528/split-string-with-delimiters-in-c](http://stackoverflow.com/questions/9210528/split-string-with-delimiters-in-c) – Gábor Angyal Jan 17 '15 at 18:26
0

Try using:

char temp_line[121]="";

Then temp_line will be initialized.

Joel
  • 4,732
  • 9
  • 39
  • 54