0

So i have this uni assignment for which i have to count votes coming from the input and sort them by the max amount(alphabetical if the number is equal). The uni server is running tests on it, putting different names/numbers in there, and i got some points already, but I'm having an issue with a certain input. This is the error I'm getting:

==30190== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==30190== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==30190== Command: ./run
==30190== 
==30190== Invalid write of size 1
==30190==    at 0x1092AA: main (program.c:23)
==30190==  Address 0x1fff001000 is not stack'd, malloc'd or (recently) free'd
==30190== 
==30190== 
==30190== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==30190==  Access not within mapped region at address 0x1FFF001000
==30190==    at 0x1092AA: main (program.c:23)
==30190==  If you believe this happened as a result of a stack
==30190==  overflow in your program's main thread (unlikely but
==30190==  possible), you can try to increase the size of the
==30190==  main thread stack using the --main-stacksize= flag.
==30190==  The main thread stack size used in this run was 8388608.
==30190== 
==30190== HEAP SUMMARY:
==30190==     in use at exit: 0 bytes in 0 blocks
==30190==   total heap usage: 1 allocs, 1 frees, 4,096 bytes allocated
==30190== 
==30190== All heap blocks were freed -- no leaks are possible
==30190== 
==30190== For counts of detected and suppressed errors, rerun with: -v
==30190== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main(){
//Declaration
    char s[20][50],st[50],sabc[20][50];
    int i,j,k,l,num[20],e[20][20],suc[20],end[20],ooo;
    for(i=0;i<20;i++){
        memset(s[i],'\0',50);
        suc[i]=0;
        for(j=0;j<20;j++){
            e[i][j]=-1;
        }
    }
//Reading the input and putting it into the s array
    gets(st);
    i=0;
    while(st[0]!='\0'){
        for(j=0;j<=strlen(st);j++){
            s[i][j]=st[j];
        }
    gets(st);
    i++;
    }
//The the individual strings are converted into just numbers and put into the num array
    for(i=0;i<20;i++){
        num[i]=atoi(s[i]);
    }
//The opposite, converting the strings into just characters, so only the names are left into the sabc array
    for(i=0;i<20;i++){
                k=0;
                for(j=0;j<50;j++){
                        if(s[i][j]<48 || s[i][j]>57){
                                sabc[i][k]=s[i][j];
                                k++;
                        }
                }
        }
//The e array, is here for letting me know at which positions are the strings with the same names.
    for(i=0;i<20;i++){
        for(j=0;j<20;j++){
            l=0;
            for(k=4;k<10;k++){
                if(s[i][k]==s[j][k]){
                    l++;
                }
            }
            if(l>5){
                e[i][j]=j;
            }   
        }
    }
//Here I'm using the previously created e array to count the number of votes together, the suc array is the number of votes counted together
    for(i=0;i<20;i++){
        for(j=0;j<20;j++){
            if(e[i][j]>=0){
                suc[i]=suc[i]+num[j];
            }
        }
    }
//Now the previous loop created duplicates, so im using this loop to remove them
    for(i=0;i<20;i++){
        if(sabc[i][0]=='\0')
            continue;
                for(j=0;j<20;j++){
            if(i==j)
                continue;
                        l=0;
                        for(k=4;k<10;k++){
                                if(sabc[i][k]==sabc[j][k]){
                                        l++;
                                }
                        }
                        if(l>5){

                                memset(sabc[j],'\0',50);
                if(suc[i]<suc[j])
                    suc[i]=suc[j];
                        }
                }
        end[i]=suc[i];
        }
//And this is the last part, sorting them by number of votes, and alphabeticaly if necessary
    memset(st,'\0',50);
    for(i=0;i<20;i++){
        for(j=0;j<20;j++){
            if(end[j]=='\0')
            break;
            if(end[j]<end[j+1]){
                for(k=0;k<50;k++){
                    st[k]=sabc[j][k];
                    sabc[j][k]=sabc[j+1][k];
                    sabc[j+1][k]=st[k];
                }
                ooo=end[j];
                end[j]=end[j+1];
                end[j+1]=ooo;
            }
            if(end[j]==end[j+1]){
                if(strcmp(sabc[j],sabc[j+1])>0){
                    for(k=0;k<50;k++){
                                            st[k]=sabc[j][k];
                                            sabc[j][k]=sabc[j+1][k];
                                            sabc[j+1][k]=st[k];
                    }
                }
            }
        }
    }
//Writing the output
    printf("Vysledky:\n");
    for(i=0;i<20;i++){
        if(sabc[i][0]=='\0')
        continue;
        printf("%d",end[i]);
        puts(sabc[i]);
    }
    return 0;
}

I know its probably not really optimized, but its what i came up with.

This part of the code just reads the string and puts it into a 2d array. Also I'm using a program called Putty connected to the uni's server, and it works fine in there, but for some reason it doesn't work on the uni site.

The input I'm having trouble with is:

4 Myne Lajad
5 Draxton Vorgthar
4 Needira Thontwi
4 Oyaka Wrathpry
5 Thrad Zex'lek

Expected output:

5 Draxton Vorgthar
5 Thrad Zex'lek
4 Myne Lajad
4 Needira Thontwi
4 Oyaka Wrathpry

The input can also contain the same names multiple times, but i have that covered. I can also provide the whole code if necessary.

Maroš
  • 1
  • 1
  • 2
    What's `st` and `s`? You should never use `gets`, it cannot check for buffer overflow. – mch Apr 07 '20 at 09:20
  • `st` is just a temporary string, which i use to move the input into the `s` array, which i work with from there on out. What would you suggest i use instead of `gets`? – Maroš Apr 07 '20 at 09:25
  • Your comment does not help. What are the exact types of these 2 variables? Show us the line where you declared them. – mch Apr 07 '20 at 09:29
  • That `for` loop could probably be replaced with `strcpy(s[i], st)`. But you need to post the entire code, this snippet makes no sense. It's not apparent how `s` is allocated either. Just post a [mcve]. – vgru Apr 07 '20 at 09:34
  • `char s[20][50],st[50];` they are both char arrays, but `s` is a 2d one. – Maroš Apr 07 '20 at 09:35
  • The whole code is there now – Maroš Apr 07 '20 at 09:58
  • Your `while` loop should be something like `while (*st && i < 20)`, but if you are only entering 5 values it shouldn't show up. Since you shouldn't use `gets`, switch to something like [`getLine` from this answer](https://stackoverflow.com/a/4309871/69809), and then replace this whole loop with `while (getLine(NULL, st, sizeof st) == OK && *st && i < 20) strcpy(s[i++], st);`. – vgru Apr 07 '20 at 10:56

0 Answers0