Расшифровка, что означают ошибки памяти отладчика Valgrind в моем коде - PullRequest
0 голосов
/ 23 сентября 2019

Довольно новый студент, чтобы прийти сюда.Только что завершил настройку подсистемы Linux, чтобы я мог запустить Valgrind для целей отладки.Я работаю над заданием, которое требует нескольких массивов строк и организованного хранения этих значений.Я полагаю, что логика моего кода разумна, однако при запуске он сразу же выходит из процесса, и у меня не остается времени даже на ввод числа попыток выполнения программы.Я считаю, что это ошибка сегментации, и скачал valgrind, чтобы точно определить проблему.Однако у меня возникают проблемы с пониманием, что означают эти сообщения об ошибках.Кажется, есть только одна или две ошибки, но я могу ошибаться.Мне может понадобиться использовать функции динамической памяти (malloc, calloc ...), чтобы заставить ее работать, но я даже больше начинающий, когда дело доходит до распределения памяти, и я не уверен даже, с чего начать.Буду очень признателен за любые советы о том, что означают мои ошибки в valgrind, или о том, как мне поступить при динамическом распределении памяти:)

Любая дополнительная информация, которая нужна кому-либо, не стесняйтесь спрашивать.

Я исключил любуюошибка, которая показала, что я знал, мог быть решен.Теперь только эти двое остаются.Я считаю, что это как-то связано с ошибкой сегментации или неправильным распределением памяти, но я не уверен.

Вот мой текущий код.Это может быть немного грязно или иметь плохие пробелы.Я также открыт для критики по поводу моего стиля кодирования:)

    int main() {
int n, i, j = 0, k, m, p, flag, key, count;
char choiceUQ, choiceSS[100];
char nameTemp[100], printStu[n][100];
char stuName[n][100], stuSym[n][n][100];        

scanf("%d", &n); //Scan in n number of times u or q will run

for(i = 0; i < n; i++) { //initialize all symptoms to be null for later if statement.
    for(k = 0; k < n; k++) {
        strcpy (stuSym[k][i], "");
    }
}

for(i = 0; i < n; i++) {
    strcpy(nameTemp, "");
    scanf("%c", &choiceUQ);
    if(choiceUQ == 'u') { 
        flag = 0; //set flag to 0, will be changed if name is already in database.
        scanf("%s", nameTemp);
        for(k = 0; k < i; k++) { //for loop checks if name is already in database.
            if(nameTemp == stuName[k]) { 
                flag = 1; //sets flag if name is in database.
                for(m = 0; m < i; m++) { //checks for next available string array spot for symptoms.
                    if(stuSym[m][k] == "")
                       scanf("%s", stuSym[m][k]);
                }
            }
        }
        if(flag == 0) { //checks for set flag, if no flag is set, it is a new name, so symptom spot will always be 0.
           strcpy(stuName[i], nameTemp);
           scanf("%s", stuSym[0][i]);
        }
}
    if(choiceUQ == 'q') {
        scanf("%s", choiceSS); //checks for input student or symptom, and executes code related to it.
        if(choiceSS == "student") {
            scanf("%s", nameTemp);
            for(k = 0; k < i; k++) { //searches for student name in database
                if(nameTemp == stuName[k]) 
                    key = k;
            }
            for(m = 0; m < i; m++) {
                printf("%s\n", stuSym[m][key]); //prints all symptoms that student has reported
            }
        }
        if(choiceSS == "symptom") {
            count = 0; //initialize count of symptoms at 0
            scanf("%s", nameTemp);
            for(k = 0; k < i; k++) {
                for(m = 0; m < i; m++) {
                   if(nameTemp == stuSym[m][k]) { //nested for loops lead to if loop to check if each student has the given symptom
                      strcpy(printStu[count], stuName[k]);
                      count++;
                    }
                }
            }
            for(p = 0; p < count; p++) { //prints all students copied into printStu array
                printf("%s", printStu[p]);
            }
        }
    }      
}

return 0;

}

Ошибка, которую я получаю в valgrind, показана ниже

==4540== error calling PR_SET_PTRACER, vgdb might block

==4540== Use of uninitialised value of size 8
==4540==    at 0x108B9C: main (santos_pandemic2.c:12)


==4540== Use of uninitialised value of size 8
==4540==    at 0x4EB7EC0: __isoc99_scanf (isoc99_scanf.c:27)

^[[A

==4540== Conditional jump or move depends on uninitialised value(s)
==4540==    at 0x108C20: main (santos_pandemic2.c:14)

==4540== Conditional jump or move depends on uninitialised value(s)
==4540==    at 0x109115: main (santos_pandemic2.c:20)

==4540== HEAP SUMMARY:
==4540==     in use at exit: 0 bytes in 0 blocks
==4540==   total heap usage: 1 allocs, 1 frees, 4,096 bytes allocated

==4540== All heap blocks were freed -- no leaks are possible

1 Ответ

2 голосов
/ 23 сентября 2019
char nameTemp[100], printStu[n][100];
char stuName[n][100], stuSym[n][n][100];

Вы используете неинициализированное значение n для объявления этих массивов.C не достаточно умен, чтобы понять, что он должен объявлять массивы после того, как вы передадите значение с помощью scanf.

Поскольку вы хотите, чтобы эти массивы распределялись динамически (используя значение, полученное из scanf), я бы предложил использовать malloc для выделения памяти для них.Или посмотрите на «массивы переменной длины» и как вы можете заставить их работать.

...