-4

This code works fine and also produces the required output, but it results to this window popping-up in the end.

enter image description here

As it can be seen, no errors or warnings are mentioned. I wish to rectify this. It is definitely not stuck in a loop, since it properly returns the required value. What could be the reason behind this issue? Please help.

Here's the code:

#include <assert.h>
#include <limits.h>
#include <math.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define size 10000

int max(int a, int b)
{
    if(a>b)
        return a;
    return b;
}

int find_subseq(char *a, char *b)
{
int i, j, la = strlen(a), lb = strlen(b);
int *arr = (int *)malloc(((la+1)*(lb+1)*sizeof(char)));

for(i = 0; i < la; i+=(lb+1))
{
    *(arr+i) = 0;
}

for(j = 0; j < lb+1; j++)
{
    *(arr+j) = 0;
}

for(i = 1; i <= la; i++)
{
    for(j = 1; j <= lb; j++)
    {
        if(*(a+i) == *(b+j))
            *(arr+i*lb+j) = *(arr+i*(lb-1)+(j-1)) + 1;
        else
            *(arr+i*lb+j) = max(*(arr+i*(lb-1)+(j)),*(arr+i*(lb)+(j-1)));
    }
}
return *(arr+la*lb+lb);
}

int main()
{
    char* a = (char *)malloc(size*sizeof(char));
    scanf("%[^\n]%*c",a);

    char* b = (char *)malloc(size*sizeof(char));
    scanf("%[^\n]%*c",b);

    printf("%d",strlen(a) + strlen(b) - (2 * find_subseq(a,b)));

    return 0;
}

later I checked on a different compiler, it gives this error:

solution: malloc.c:2394: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.

GDB trace:
Reading symbols from solution...done.
[New LWP 10243]
Core was generated by `solution'.
Program terminated with signal SIGABRT, Aborted.
#0  0x00007f622e4b2428 in __GI_raise (sig=sig@entry=6)
    at ../sysdeps/unix/sysv/linux/raise.c:54
#0  0x00007f622e4b2428 in __GI_raise (sig=sig@entry=6)
    at ../sysdeps/unix/sysv/linux/raise.c:54
#1  0x00007f622e4b402a in __GI_abort () at abort.c:89
#2  0x00007f622e4fa2e8 in __malloc_assert (
    assertion=assertion@entry=0x7f622e60e190 "(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)", 
    file=file@entry=0x7f622e60abc5 "malloc.c", line=line@entry=2394, 
    function=function@entry=0x7f622e60e9d8 <__func__.11509> "sysmalloc")
    at malloc.c:301
#3  0x00007f622e4fe426 in sysmalloc (nb=nb@entry=4112, 
    av=av@entry=0x7f622e841b20 <main_arena>) at malloc.c:2391
#4  0x00007f622e4ff743 in _int_malloc (
    av=av@entry=0x7f622e841b20 <main_arena>, bytes=bytes@entry=4096)
    at malloc.c:3827
#5  0x00007f622e501184 in __GI___libc_malloc (bytes=bytes@entry=4096)
    at malloc.c:2913
#6  0x00007f622e4ea1d5 in __GI__IO_file_doallocate (
    fp=0x7f622e842620 <_IO_2_1_stdout_>) at filedoalloc.c:127
#7  0x00007f622e4f8594 in __GI__IO_doallocbuf (
    fp=fp@entry=0x7f622e842620 <_IO_2_1_stdout_>) at genops.c:398
#8  0x00007f622e4f78f8 in _IO_new_file_overflow (
    f=0x7f622e842620 <_IO_2_1_stdout_>, ch=-1) at fileops.c:820
#9  0x00007f622e4f628d in _IO_new_file_xsputn (
    f=0x7f622e842620 <_IO_2_1_stdout_>, data=0x7ffe22f98f77, n=1)
    at fileops.c:1331
#10 0x00007f622e4cae00 in _IO_vfprintf_internal (
    s=0x7f622e842620 <_IO_2_1_stdout_>, format=<optimized out>, 
    format@entry=0x4008dd "%zu", ap=ap@entry=0x7ffe22f98fc8)
    at vfprintf.c:1631
#11 0x00007f622e5939ef in ___printf_chk (flag=flag@entry=1, 
    format=format@entry=0x4008dd "%zu") at printf_chk.c:35
#12 0x000000000040062b in printf (__fmt=0x4008dd "%zu")
    at /usr/include/x86_64-linux-gnu/bits/stdio2.h:104
#13 main () at solution.c:56

What does this mean? Is this the reason for crash?

PKBEST
  • 321
  • 2
  • 13
  • 1
    Your format string is scanning a single character, but you treat it as string. – Eugene Sh. May 11 '18 at 15:52
  • 1
    Hint: Programs that crash nearly *always* have errors, so the title supposition is invalid. Unrelated, good lord, in case you didn't know (and judging by this code, you don't) `strlen` isn't free. Each invoke scans the input string from beginning to terminator. – WhozCraig May 11 '18 at 15:52
  • Code crashes, yet no checks on `malloc()` results nor checks on `scanf()` results. It seems 1st step would be to add code checking those - even if this is not related to the problem, it is good defensive programming to catch the easy things. – chux - Reinstate Monica May 11 '18 at 15:56
  • 1
    `int *arr = (int *)malloc(((strlen(a)+1)*(strlen(b)+1)*sizeof(char)));` looks very wrong. Why `int` and `char`? Try `int *arr = calloc(sizeof *arr, (strlen(a)+1)*(strlen(b)+1));` – chux - Reinstate Monica May 11 '18 at 15:58
  • I compiled on ideone... there it was successful, but the compiler in hackerRank says this... – PKBEST May 11 '18 at 15:59
  • solution.c: In function ‘main’: solution.c:56:14: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘size_t {aka long unsigned int}’ [-Wformat=] printf("%d",(strlen(a) + strlen(b) - (2 * find_subseq(a,b)))); ~^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ %ld – PKBEST May 11 '18 at 15:59
  • That's yet another problem: On most 64-bit platforms, that `strlen(a)` is going to be a 64-bit int, but you're printing it as a 32-bit int. Most compilers will give you warnings for these problems, and you should not ignore those warnings. If yours doesn't (and it's not because of some weird config you're using), get a linter. – abarnert May 11 '18 at 16:00
  • @PKBEST Use `printf("%zu"...` to fix that. – chux - Reinstate Monica May 11 '18 at 16:00
  • @PKBEST "Is this the reason for crash?" --> Likely. Please report on [this comment](https://stackoverflow.com/questions/50295854/program-has-no-errors-but-still-crashes#comment87609006_50295854). – chux - Reinstate Monica May 11 '18 at 16:15
  • That works!... Can you explain why? – PKBEST May 11 '18 at 16:18

1 Answers1

2

First thing always free() allocated memory. In your main() function you didn't free array a and array b. This is not an error but it is bad for your program to leave it like that

Second, in your find_subseq function when you are allocating memory for array arr you can not say int* array = malloc(... *sizeof(char)); It must be int *array=malloc(... *sizeof(int))

//this is wrong
int *arr = (int *)malloc(((la+1)*(lb+1)*sizeof(char)));
//this is right
int *arr = (int *)malloc(((la+1)*(lb+1)*sizeof(int)));

Third, in those for loops in find_subseq functions indexes go out of range. This is huge problem because you will try to access array member which is not in range for that particular array. This causes undefined behavior in your program.

for(j = 0; j < lb+1; j++)

when j=lb in last iteration you will try to access array[lb], but the indexes go from 0 to lb-1

Maybe if you explain what are you trying to do in your program i could help you more.

Aleksa Jovanovic
  • 207
  • 3
  • 15
  • Using `sizeof *arr` instead of `sizeof(int)` avoids the coding mistake, easier to review and maintain. – chux - Reinstate Monica May 11 '18 at 16:34
  • Very good answer, with one exception: this: "it will cause memory fragmentation which is very bad for your program" is nonsense, I'm afraid. Neglecting to free all memory before exit can be a problem for a programming project or not, depending on the needs of the project, but it will *not* lead to any "fragmentation" (or, for that matter, loss) of memory. We can say that it's a potential problem, but we shouldn't say it's automatically a bad problem. – Steve Summit May 11 '18 at 16:39
  • All my teachers on university say that you must free allocated memory because it is very bad for program to leave it like that (for every allocated variable in program that you didn't use free you get -2 points on test). I thought it will make memory fragmentation... Now, after you said this, i will read about it. Thank you – Aleksa Jovanovic May 11 '18 at 18:06
  • @AleksaJovanovic I understand about your teachers. It's a question with a lot of conflicting opinions surrounding it. See [this question](https://stackoverflow.com/questions/36584062). – Steve Summit May 11 '18 at 19:03
  • @AleksaJovanovic This program returns the length of the longest common subsequence between the two strings. (I guess the index range isn't going out of bounds because the array is not n*m, its (n+1)*(m+1). – PKBEST May 11 '18 at 19:46