Search code examples
ciostdinfgetsscanf

Problems with taking input from stdin - Invalid read/write from valgrind


I ran valgrind on a program I'm working on and I'm getting the following errors - I can't figure out why. Any help would be greatly appreciated ahead of time. Let me know if you need any more information

==27928== Invalid read of size 1
==27928==    at 0x4EB9390: __GI___rawmemchr (rawmemchr.S:25)
==27928==    by 0x4EA514F: _IO_str_init_static_internal (strops.c:45)
==27928==    by 0x4E86D64: __isoc99_vsscanf (isoc99_vsscanf.c:42)
==27928==    by 0x4E86CF7: __isoc99_sscanf (isoc99_sscanf.c:33)
==27928==    by 0x401A76: countAndSort (lab1.c:442)
==27928==    by 0x4014EB: doProcess (lab1.c:316)
==27928==    by 0x4011C2: main (lab1.c:211)
==27928==  Address 0x55bb040 is 0 bytes inside a block of size 10,000,000 free'd
==27928==    at 0x4C27D4E: free (vg_replace_malloc.c:427)
==27928==    by 0x4019D6: countAndSort (lab1.c:430)
==27928==    by 0x4014EB: doProcess (lab1.c:316)
==27928==    by 0x4011C2: main (lab1.c:211)
==27928==
==27928== Invalid read of size 1
==27928==    at 0x4C2B834: __GI___rawmemchr (mc_replace_strmem.c:1110)
==27928==    by 0x4EA514F: _IO_str_init_static_internal (strops.c:45)
==27928==    by 0x4E86D64: __isoc99_vsscanf (isoc99_vsscanf.c:42)
==27928==    by 0x4E86CF7: __isoc99_sscanf (isoc99_sscanf.c:33)
==27928==    by 0x401A76: countAndSort (lab1.c:442)
==27928==    by 0x4014EB: doProcess (lab1.c:316)
==27928==    by 0x4011C2: main (lab1.c:211)
==27928==  Address 0x55bb041 is 1 bytes inside a block of size 10,000,000 free'd
==27928==    at 0x4C27D4E: free (vg_replace_malloc.c:427)
==27928==    by 0x4019D6: countAndSort (lab1.c:430)
==27928==    by 0x4014EB: doProcess (lab1.c:316)
==27928==    by 0x4011C2: main (lab1.c:211)
==27928==
==27928== Invalid read of size 1
==27928==    at 0x4E7D920: _IO_vfscanf (vfscanf.c:620)
==27928==    by 0x4E86D79: __isoc99_vsscanf (isoc99_vsscanf.c:44)
==27928==    by 0x4E86CF7: __isoc99_sscanf (isoc99_sscanf.c:33)
==27928==    by 0x401A76: countAndSort (lab1.c:442)
==27928==    by 0x4014EB: doProcess (lab1.c:316)
==27928==    by 0x4011C2: main (lab1.c:211)
==27928==  Address 0x55bb040 is 0 bytes inside a block of size 10,000,000 free'd
==27928==    at 0x4C27D4E: free (vg_replace_malloc.c:427)
==27928==    by 0x4019D6: countAndSort (lab1.c:430)
==27928==    by 0x4014EB: doProcess (lab1.c:316)
==27928==    by 0x4011C2: main (lab1.c:211)
==27928==
==27928== Invalid read of size 1
==27928==    at 0x4EA36D2: _IO_sputbackc (genops.c:731)
==27928==    by 0x4E7D97B: _IO_vfscanf (vfscanf.c:625)
==27928==    by 0x4E86D79: __isoc99_vsscanf (isoc99_vsscanf.c:44)
==27928==    by 0x4E86CF7: __isoc99_sscanf (isoc99_sscanf.c:33)
==27928==    by 0x401A76: countAndSort (lab1.c:442)
==27928==    by 0x4014EB: doProcess (lab1.c:316)
==27928==    by 0x4011C2: main (lab1.c:211)
==27928==  Address 0x55bb040 is 0 bytes inside a block of size 10,000,000 free'd
==27928==    at 0x4C27D4E: free (vg_replace_malloc.c:427)
==27928==    by 0x4019D6: countAndSort (lab1.c:430)
==27928==    by 0x4014EB: doProcess (lab1.c:316)
==27928==    by 0x4011C2: main (lab1.c:211)
==27928==
==27928== Invalid read of size 1
==27928==    at 0x4E7DC7D: _IO_vfscanf (vfscanf.c:1394)
==27928==    by 0x4E86D79: __isoc99_vsscanf (isoc99_vsscanf.c:44)
==27928==    by 0x4E86CF7: __isoc99_sscanf (isoc99_sscanf.c:33)
==27928==    by 0x401A76: countAndSort (lab1.c:442)
==27928==    by 0x4014EB: doProcess (lab1.c:316)
==27928==    by 0x4011C2: main (lab1.c:211)
==27928==  Address 0x55bb040 is 0 bytes inside a block of size 10,000,000 free'd
==27928==    at 0x4C27D4E: free (vg_replace_malloc.c:427)
==27928==    by 0x4019D6: countAndSort (lab1.c:430)
==27928==    by 0x4014EB: doProcess (lab1.c:316)
==27928==    by 0x4011C2: main (lab1.c:211)
==27928==
==27928== Invalid read of size 1
==27928==    at 0x4E7E9EF: _IO_vfscanf (vfscanf.c:1781)
==27928==    by 0x4E86D79: __isoc99_vsscanf (isoc99_vsscanf.c:44)
==27928==    by 0x4E86CF7: __isoc99_sscanf (isoc99_sscanf.c:33)
==27928==    by 0x401A76: countAndSort (lab1.c:442)
==27928==    by 0x4014EB: doProcess (lab1.c:316)
==27928==    by 0x4011C2: main (lab1.c:211)
==27928==  Address 0x55bb041 is 1 bytes inside a block of size 10,000,000 free'd
==27928==    at 0x4C27D4E: free (vg_replace_malloc.c:427)
==27928==    by 0x4019D6: countAndSort (lab1.c:430)
==27928==    by 0x4014EB: doProcess (lab1.c:316)
==27928==    by 0x4011C2: main (lab1.c:211)
==27928==
==27928== Invalid read of size 1
==27928==    at 0x4EA36D2: _IO_sputbackc (genops.c:731)
==27928==    by 0x4E7DDF3: _IO_vfscanf (vfscanf.c:1811)
==27928==    by 0x4E86D79: __isoc99_vsscanf (isoc99_vsscanf.c:44)
==27928==    by 0x4E86CF7: __isoc99_sscanf (isoc99_sscanf.c:33)
==27928==    by 0x401A76: countAndSort (lab1.c:442)
==27928==    by 0x4014EB: doProcess (lab1.c:316)
==27928==    by 0x4011C2: main (lab1.c:211)
==27928==  Address 0x55bb041 is 1 bytes inside a block of size 10,000,000 free'd
==27928==    at 0x4C27D4E: free (vg_replace_malloc.c:427)
==27928==    by 0x4019D6: countAndSort (lab1.c:430)
==27928==    by 0x4014EB: doProcess (lab1.c:316)
==27928==    by 0x4011C2: main (lab1.c:211)
==27928==

Regardless of what you might think from the origin of each error, through lots of trial and error, commenting out/back in blocks of code and separately testing pieces of code in test compilations, I've found that the following is the erroneous source. If I comment this code out in my program, all errors go away.

NOTE: integers is a global int* type. countToUse is a global int type. The goal of the code here is to read all integers from stdin and get them into a correctly sized dynamic array.

            // Load stdin into a buffer
            char *buffer = malloc(BUFFER_SIZE);
            if(buffer == NULL){
                    fprintf(stderr, "Malloc for stdin buffer in countAndSort() failed. Exiting.\n");
                    exit(1);
            }
            if (fgets(buffer, BUFFER_SIZE, stdin) == NULL) {
                    fprintf(stderr, "Error loading input from stdin into buffer. Exiting.\n");
                    exit(1);
            }

            // Get a count of the numbers to create the array
            int count = 0;
            int index = 0;
            int num, delta;
            while (index < BUFFER_SIZE && sscanf(&buffer[index], "%d%n", &num, &delta) == 1){
                    count++;
                    index += delta;
            }

            // Initialize the array with the proper size
            integers = malloc(count*sizeof(int));
            if(integers == NULL){
                    fprintf(stderr, "Malloc for integer array in countAndSort() failed. Exiting. \n");
                    exit(1);
            }

            // Load the integers into the array
            index = 0;
            for (int i = 0; i < count; i++){
// LINE 442 IS RIGHT BELOW THIS LINE ------------------------------------
                    if (index < BUFFER_SIZE && sscanf(&buffer[index], "%d%n", &integers[i], &delta) != 1){
                            fprintf(stderr, "There was a problem reading the buffer!\n");
                            exit(1);
                    }
                    index += delta;
            }

            if(buffer != NULL)
                    free(buffer);

            countToUse = count;

Solution

  • You need to make sure you are not reading beyond the bounds of buffer, like this

    while ((index < 10000000) && (sscanf(&buffer[index], "%d%n", &num, &delta) == 1))
    

    and the same applies for all the buffer[index]'s.

    Also, from the error it seems that you have free()d buffer and then attempted to read from it.