G
G
George1232020-11-08 01:05:19
C++ / C#
George123, 2020-11-08 01:05:19

How to find wrong work with memory?

The essence of the problem is this: when the number -8147483645 is given as input in the txt file, the program gives an incorrect answer (when, for example, when choosing "+1", the number 442450948 is given). As far as I understand, this is some kind of jamb in my work with memory. I managed to find out that somewhere in the num_convert function there is a memory overflow, hence the wrong answer. But I couldn't figure out exactly where this is happening, so I'm asking for help in finding the problem. I am quoting , in fact, the code itself:

the num_convert function simply moves each digit of the number to an array

void num_convert(long long int num, int ord, long long int* mas, long long int** p)
{

    int counter=ord;
    printf("num %lld\n",num);
    int flag=0;
    int sign=num/abs(num);
    num=abs(num);
    mas=realloc(mas,(ord+1)*sizeof(long long int));
    while (1==1)
    {
        if (num/10==0 && flag==1)
        {
            break;
        }

        if (num/10==0 && flag==0)
        {
            mas[0]=num%10;
            flag++;
        }
        else
        {
            mas[counter]=num%10;
            num=num/10;
            counter--;
        }
    }
    if (sign==-1)
    {
        mas[0]=-1*mas[0];
    }
    *p=mas;
}


The following is the function responsible for "interaction with the user", I give it so that it is approximately clear what is happening in the program in general and where it can break.

int main(void)
{

    long long int** p;
    long long int *m;
    int sw=0;
    int size=0;
    int ord=0;
    long long int n=0;
    int o=0;
    char file_name[255];
    m=(long long int* )malloc(sizeof(long long int));
    p=&m;


    printf("Choose one of the options:\n");
    printf("Enter 1 if you have the number of the elements in your file\n");
    printf("Enter 2 if you do not have the number of the elements in your file\n");
    printf("Enter 3 to shut down the program\n");
    printf(":");
    scanf("%d",&sw);

    switch(sw)
    {
        case(3):
            free(m);
            return 0;
        case(1):
            printf("Enter the name of the file \n");
            scanf("%s", file_name);
            size=read_1(m,file_name,p);
            break;
        case(2):
            printf("Enter the name of the file \n");
            scanf("%s", file_name);
            size=read_2(m,file_name,p);
            break;
    }

    if (size<1)
    {
        printf("An error occured\n");
        free(m);
        return -1;
    }

    n=arr_convert(m,size);
    ord=get_ord(n);
    printf("Choose the scenario (enter +1 or -1) \n");
    scanf("%d",&o);

    switch(o)
    {
        case(1):
            n=n+1;
            ord=get_ord(n);
            num_convert(n,ord,m,p);
            for (int y=0;y<=ord;y++)
            {
                printf("%lld ",m[y]);
            }
            free(m);
            return 0;
        case(-1):
            n=n+1;
            ord=get_ord(n);
            num_convert(n,ord,m,p);
            for (int y=0;y<=ord;y++)
            {
                printf("%lld ",m[y]);
            }
            free(m);
            return 0;
    }
}


And this is the output of valgrind

==6016== Invalid write of size 8
==6016==    at 0x109467: num_convert (in /home/georgy/Рабочий стол/5 домашка/progr)
==6016==    by 0x108CDC: main (in /home/georgy/Рабочий стол/5 домашка/progr)
==6016==  Address 0x55ccc90 is 16 bytes after a block of size 48 in arena "client"
==6016== 
==6016== Conditional jump or move depends on uninitialised value(s)
==6016==    at 0x523696A: vfprintf (vfprintf.c:1642)
==6016==    by 0x523EFA5: printf (printf.c:33)
==6016==    by 0x108D16: main (in /home/georgy/Рабочий стол/5 домашка/progr)
==6016== 
==6016== Use of uninitialised value of size 8
==6016==    at 0x52328FB: _itoa_word (_itoa.c:179)
==6016==    by 0x5235F9D: vfprintf (vfprintf.c:1642)
==6016==    by 0x523EFA5: printf (printf.c:33)
==6016==    by 0x108D16: main (in /home/georgy/Рабочий стол/5 домашка/progr)
==6016== 
==6016== Conditional jump or move depends on uninitialised value(s)
==6016==    at 0x5232905: _itoa_word (_itoa.c:179)
==6016==    by 0x5235F9D: vfprintf (vfprintf.c:1642)
==6016==    by 0x523EFA5: printf (printf.c:33)
==6016==    by 0x108D16: main (in /home/georgy/Рабочий стол/5 домашка/progr)
==6016== 
==6016== Conditional jump or move depends on uninitialised value(s)
==6016==    at 0x52360A4: vfprintf (vfprintf.c:1642)
==6016==    by 0x523EFA5: printf (printf.c:33)
==6016==    by 0x108D16: main (in /home/georgy/Рабочий стол/5 домашка/progr)
==6016== 
==6016== Conditional jump or move depends on uninitialised value(s)
==6016==    at 0x5236BDC: vfprintf (vfprintf.c:1642)
==6016==    by 0x523EFA5: printf (printf.c:33)
==6016==    by 0x108D16: main (in /home/georgy/Рабочий стол/5 домашка/progr)
==6016== 
==6016== Invalid read of size 8
==6016==    at 0x108D00: main (in /home/georgy/Рабочий стол/5 домашка/progr)
==6016==  Address 0x55ccc78 is 4 bytes after a block of size 36 alloc'd
==6016==    at 0x4C31D2F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6016==    by 0x1093AA: num_convert (in /home/georgy/Рабочий стол/5 домашка/progr)
==6016==    by 0x108CDC: main (in /home/georgy/Рабочий стол/5 домашка/progr)


It is noteworthy that there are no memory leaks as such (according to valgrind itself)

Answer the question

In order to leave comments, you need to log in

1 answer(s)
J
jcmvbkbc, 2020-11-08
@Georgy123

How to find wrong work with memory?

Uncompile and link your program with the option -g, then valgrind will poke you right into the problematic line.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question