Liam B
Liam B

Reputation: 25

A random character showing up at the end of a C array

I have the code:

else if ((strtolnum=(strtol(&oldline[b+1],NULL,10)))>0)
        {
            char* excl = malloc(3*sizeof(char));
            excl[0]=oldline[b];
            excl[1]=oldline[b+1];
            for (int j = 0; j<strtolnum; j++)
            {
                llist=llist->nextcmd;
            }
            struct token *p1;
            struct token *save1 = llist->cmmd;
            char *arra1 = malloc(sizeof(char));
            memset(arra1, '\0', 1);
            for (p1 = llist->cmmd;  p1 != NULL;  p1 = p1->next) {
                arra = realloc(arra1, strlen(arra1)+strlen(p1->text)+2);
                strcat(arra, p1->text);
                if (p1->next!=NULL)
                {
                    strcat(arra1, " ");
                }//   printing token and type
            }
            printf("%s excl\n", excl); //Line 137
            oldline=strreplace(oldline,excl,arra1); //Line 138
            llist->cmmd=save1;
            for (int j = 0; j<(f-strtolnum); j++)
            {
                llist=llist->nextcmd;
            }
            *status=1;
            size_t a = sizeof(excl);
            memset(excl,'\0', a);
        }

What the code should accomplish is get the first integer of a line which is preceded by an exclamation part, such as !3, and puts it in excl (and then do other stuff which is working perfectly fine).

However, when I run the loop more than once, I find that excl often has a random character at the end, such as when it shows up as "!3e" when I try to printf it. Valgrind shows the following errors:

==24878== Conditional jump or move depends on uninitialised value(s)
==24878==    at 0x4E7AB5B: vfprintf (in /usr/lib64/libc-2.17.so)
==24878==    by 0x4E83CD8: printf (in /usr/lib64/libc-2.17.so)
==24878==    by 0x40130F: hExpand (Lex1.c:137)
==24878==    by 0x400B6B: main (mainLex.c:27)
==24878== 
==24878== Conditional jump or move depends on uninitialised value(s)
==24878==    at 0x4C2B308: strlen (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==24878==    by 0x4020D7: strreplace (Lex1.c:562)
==24878==    by 0x40132C: hExpand (Lex1.c:138)

Apparently, excl is unititialized after the loop goes through once. What is wrong?

For additional information, cmmd is a data structure of type token, and llist is a global static data structure containing tokens.

Upvotes: 0

Views: 449

Answers (1)

Jonathan Leffler
Jonathan Leffler

Reputation: 754710

You haven't null terminated the excl string; malloc() returns random garbage. You might think about adding:

excl[2] = '\0';

You also trample way out of bounds with:

size_t a = sizeof(excl);
memset(excl,'\0', a);

You assign either 4 or 8 (32-bit or 64-bit) to a, and then write over that many bytes, but you only allocated 3 bytes for excl.

Upvotes: 3

Related Questions