valgrind:条件跳转或移动取决于未初始化的值

问题描述 投票:0回答:1

我是 C 新手。最近,我试图制作一些函数,使我能够与动态分配的数组进行交互。我并不认为我编写的函数是好的,但它确实有效。我尝试使用

valgrind --tool=memcheck --leak-check=yes ./program
检查我的代码是否存在内存泄漏,运行后它给了我很多 条件跳转或移动取决于单位化值。我尝试运行
valgrind --track-origins=yes ./program
但由于我不太擅长代码,所以我并没有真正得到一些东西。顺便说一句,我使用 Debian WSL(如果有的话)。我只是想确切地知道那是什么以及为什么会发生这个“错误”,因为我想避免任何会破坏我的程序未来假设性能的事情。

提前致谢!

程序.c

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

struct array {
    int* data;
    int items;
    int capacity;
    int space;
};
  
void removeArr(struct array *arr, int index);
void sortArr(struct array *arr, bool reverse);
void printArr(struct array *arr, int limit);
void appendArr(struct array *arr, int item);
void insertArr(struct array *arr, int index, int item);
  
int main() {
    struct array a1;
    int i = 0;
  
    a1.items = 0;
    a1.capacity = 10;
    a1.space = 5;
    a1.data = (int*)malloc(a1.capacity * sizeof(int));
    if(NULL == a1.data) {
        printf("Allocation for a1.data failed\n");
        return 1;
    }
  
    // Filling up the array with 5 elements
    for(i = 0; i < a1.capacity - 5; i++) {
        a1.data[i] = i + 1;
        a1.items++;
    }
  
    // Testing appending, inserting and removing from an array
    appendArr(&a1, 6);
    appendArr(&a1, 7);
    insertArr(&a1, 1, 10);
    insertArr(&a1, a1.items, 3);
    removeArr(&a1, a1.items - 1);
    printf("Before For Loop: %d %d\n", a1.capacity, a1.items);
    printArr(&a1, 5);
  
    // Testing appending inside the for loop
    for(i = 0; i < 2; i++) appendArr(&a1, i + 15);
    printf("After For Loop: %d %d\n", a1.capacity, a1.items);
    printArr(&a1, 5);
  
    // Testing insert func when there's no free space in the array
    insertArr(&a1, 1, 100);
    printf("After insert with extra space: %d %d\n", a1.capacity, a1.items);
    printArr(&a1, 5);
    // Testing reverse (bubble) sort
    putchar('\n');
    sortArr(&a1, true);
    printArr(&a1, 5);
  
    // Testing standard (bubble) sort
    putchar('\n');
    sortArr(&a1, false);
    printArr(&a1, 5);
  
    // Overwriting the entire array
    putchar('\n');
    for(i = 0; i < a1.capacity; i++) {
        a1.data[i] = i + 1;
    }
    a1.items = a1.capacity;
  
    // Testing inserting inside the for loop
    for(i = 1; i <= 15; i++) {
        insertArr(&a1, i, i);
    }
    putchar('\n');
    printArr(&a1, 5);
  
    // Check the curren capacity and items amount after all of the operations with the array
    printf("After Insert For Loop: %d %d\n", a1.capacity, a1.items);
  
    // Freeing the dynamically allocated array
    free(a1.data);
    a1.data = NULL;
    return 0;
}
  
void removeArr(struct array *arr, int index) {
    if(0 >= index || index >= arr->capacity) {
        printf("ERROR: Index is incorrect\n");
        exit(1);
    }
    for(int i = index; i < arr->capacity; i++) {
        if(0 == arr->data[i - 1] && 0 == arr->data[i]) {
            continue;
        }
        arr->data[i - 1] = arr->data[i];
    }
    arr->data[arr->capacity - 1] = 0;
    arr->items--;
}
  
void sortArr(struct array *arr, bool reverse) {
    int i = 0;
    bool swapped;
    if(false == reverse) {
        do {
            swapped = false;
            for(int j = 0; j < (arr->capacity - 1 - i); j++) {
                if(arr->data[j + 1] < arr->data[j]) {
                    int temp = arr->data[j];
                    arr->data[j] = arr->data[j + 1];
                    arr->data[j + 1] = temp;
                    swapped = true;
                }
            }
            i++;
        }
        while(swapped)
            ;
    }
  
    if(true == reverse) {
        do {
            swapped = false;
            for(int j = 0; j < (arr->capacity - 1 - i); j++) {
                if(arr->data[j + 1] > arr->data[j]) {
                    int temp = arr->data[j];
                    arr->data[j] = arr->data[j + 1];
                    arr->data[j + 1] = temp;
                    swapped = true;
                }
            }
            i++;
        }
        while(swapped)
            ;
    }
}
  
void printArr(struct array *arr, int limit) {
    int pos = 0;
    for(int i = 0; i < arr->capacity; i++) {
        if(pos < limit) {
            printf("%d ", arr->data[i]);
            pos++;
        }
        else {
            putchar('\n');
            printf("%d ", arr->data[i]);
            pos = 1;
        }
    }
    putchar('\n');
}
  
void appendArr(struct array *arr, int item) {
    if(arr->items == arr->capacity) {
        arr->capacity += arr->space;
        arr->data = (int*)realloc(arr->data, arr->capacity * sizeof(int));
        if(NULL == arr->data) {
            printf("Reallocation for arr->data failed while appending.\n");
            exit(1);
        }
    }
    arr->data[arr->items] = item;
    arr->items++;
}
  
void insertArr(struct array *arr, int index, int item) {
    if(0 >= index || index >= arr->capacity) {
        printf("ERROR: Index is incorrect\n");
        exit(1);
    }
    if(index == arr->items) {
        appendArr(arr, item);
    }
    else if(index > 0 && index < arr->capacity) {
        if(arr->items == arr->capacity) {
            arr->capacity += arr->space;
            arr->data = (int*)realloc(arr->data, arr->capacity * sizeof(int));
            if(NULL == arr->data) {
                printf("Reallocation for arr->data failed when inserting.\n");
                exit(1);
            }
        }
        for(int i = arr->capacity - 1; i >= index; i--) {
            if(0 == arr->data[i] && 0 == arr->data[i - 1])
                continue;
  
            arr->data[i] = arr->data[i - 1];
        }
        arr->data[index - 1] = item;
        arr->items++;
    }
    else {
        printf("Unexpected error occured while insertion.\n");
        exit(2);
    }
}

valgrind --tool=memcheck --leak-check=yes ./program
输出:

==14958== Memcheck, a memory error detector
==14958== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==14958== Using Valgrind-3.19.0 and LibVEX; rerun with -h for copyright info
==14958== Command: ./dev/test
==14958== 
==14958== Conditional jump or move depends on uninitialised value(s)
==14958==    at 0x1099BA: insertArr (test.c:192)
==14958==    by 0x109265: main (test.c:40)
==14958== 
==14958== Conditional jump or move depends on uninitialised value(s)
==14958==    at 0x1099D8: insertArr (test.c:192)
==14958==    by 0x109265: main (test.c:40)
==14958== 
Before For Loop: 10 8
10 1 2 3 4 5 
==14958== Conditional jump or move depends on uninitialised value(s)
==14958==    at 0x48B8027: __vfprintf_internal (vfprintf-process-arg.c:58)
==14958==    by 0x48AD65A: printf (printf.c:33)
==14958==    by 0x109786: printArr (test.c:147)
==14958==    by 0x1092BC: main (test.c:44)
==14958== 
==14958== Use of uninitialised value of size 8
==14958==    at 0x48ACAAB: _itoa_word (_itoa.c:177)
==14958==    by 0x48B7E58: __vfprintf_internal (vfprintf-process-arg.c:164)
==14958==    by 0x48AD65A: printf (printf.c:33)
==14958==    by 0x109786: printArr (test.c:147)
==14958==    by 0x1092BC: main (test.c:44)
==14958== 
==14958== Conditional jump or move depends on uninitialised value(s)
==14958==    at 0x48ACABC: _itoa_word (_itoa.c:177)
==14958==    by 0x48B7E58: __vfprintf_internal (vfprintf-process-arg.c:164)
==14958==    by 0x48AD65A: printf (printf.c:33)
==14958==    by 0x109786: printArr (test.c:147)
==14958==    by 0x1092BC: main (test.c:44)
==14958== 
==14958== Conditional jump or move depends on uninitialised value(s)
==14958==    at 0x48B86F6: __vfprintf_internal (vfprintf-process-arg.c:174)
==14958==    by 0x48AD65A: printf (printf.c:33)
==14958==    by 0x109786: printArr (test.c:147)
==14958==    by 0x1092BC: main (test.c:44)
==14958== 
6 3 0 0 
After For Loop: 10 10
10 1 2 3 4 5 
6 3 15 16 
==14958== Conditional jump or move depends on uninitialised value(s)
==14958==    at 0x1099BA: insertArr (test.c:192)
==14958==    by 0x109326: main (test.c:52)
==14958== 
==14958== Conditional jump or move depends on uninitialised value(s)
==14958==    at 0x1099D8: insertArr (test.c:192)
==14958==    by 0x109326: main (test.c:52)
==14958== 
After insert with extra space: 15 11
100 10 1 2 3 4 
==14958== Conditional jump or move depends on uninitialised value(s)
==14958==    at 0x48B8027: __vfprintf_internal (vfprintf-process-arg.c:58)
==14958==    by 0x48AD65A: printf (printf.c:33)
==14958==    by 0x109786: printArr (test.c:147)
==14958==    by 0x109353: main (test.c:54)
==14958== 
==14958== Conditional jump or move depends on uninitialised value(s)
==14958==    at 0x48B86F6: __vfprintf_internal (vfprintf-process-arg.c:174)
==14958==    by 0x48AD65A: printf (printf.c:33)
==14958==    by 0x109786: printArr (test.c:147)
==14958==    by 0x109353: main (test.c:54)
==14958== 
5 6 3 15 16 0 
==14958== Conditional jump or move depends on uninitialised value(s)
==14958==    at 0x48B8027: __vfprintf_internal (vfprintf-process-arg.c:58)
==14958==    by 0x48AD65A: printf (printf.c:33)
==14958==    by 0x1097C2: printArr (test.c:152)
==14958==    by 0x109353: main (test.c:54)
==14958== 
==14958== Use of uninitialised value of size 8
==14958==    at 0x48ACAAB: _itoa_word (_itoa.c:177)
==14958==    by 0x48B7E58: __vfprintf_internal (vfprintf-process-arg.c:164)
==14958==    by 0x48AD65A: printf (printf.c:33)
==14958==    by 0x1097C2: printArr (test.c:152)
==14958==    by 0x109353: main (test.c:54)
==14958== 
==14958== Conditional jump or move depends on uninitialised value(s)
==14958==    at 0x48ACABC: _itoa_word (_itoa.c:177)
==14958==    by 0x48B7E58: __vfprintf_internal (vfprintf-process-arg.c:164)
==14958==    by 0x48AD65A: printf (printf.c:33)
==14958==    by 0x1097C2: printArr (test.c:152)
==14958==    by 0x109353: main (test.c:54)
==14958== 
==14958== Conditional jump or move depends on uninitialised value(s)
==14958==    at 0x48B86F6: __vfprintf_internal (vfprintf-process-arg.c:174)
==14958==    by 0x48AD65A: printf (printf.c:33)
==14958==    by 0x1097C2: printArr (test.c:152)
==14958==    by 0x109353: main (test.c:54)
==14958== 
0 0 0 

==14958== Conditional jump or move depends on uninitialised value(s)
==14958==    at 0x10969C: sortArr (test.c:129)
==14958==    by 0x10936E: main (test.c:58)
==14958== 
100 16 15 10 6 5 
==14958== Conditional jump or move depends on uninitialised value(s)
==14958==    at 0x48B8027: __vfprintf_internal (vfprintf-process-arg.c:58)
==14958==    by 0x48AD65A: printf (printf.c:33)
==14958==    by 0x109786: printArr (test.c:147)
==14958==    by 0x10937F: main (test.c:59)
==14958== 
==14958== Conditional jump or move depends on uninitialised value(s)
==14958==    at 0x48B86F6: __vfprintf_internal (vfprintf-process-arg.c:174)
==14958==    by 0x48AD65A: printf (printf.c:33)
==14958==    by 0x109786: printArr (test.c:147)
==14958==    by 0x10937F: main (test.c:59)
==14958== 
4 3 3 2 1 0 
==14958== Conditional jump or move depends on uninitialised value(s)
==14958==    at 0x48B8027: __vfprintf_internal (vfprintf-process-arg.c:58)
==14958==    by 0x48AD65A: printf (printf.c:33)
==14958==    by 0x1097C2: printArr (test.c:152)
==14958==    by 0x10937F: main (test.c:59)
==14958== 
==14958== Conditional jump or move depends on uninitialised value(s)
==14958==    at 0x48B86F6: __vfprintf_internal (vfprintf-process-arg.c:174)
==14958==    by 0x48AD65A: printf (printf.c:33)
==14958==    by 0x1097C2: printArr (test.c:152)
==14958==    by 0x10937F: main (test.c:59)
==14958== 
0 0 0 

==14958== Conditional jump or move depends on uninitialised value(s)
==14958==    at 0x1095BB: sortArr (test.c:112)
==14958==    by 0x10939A: main (test.c:63)
==14958== 
==14958== Conditional jump or move depends on uninitialised value(s)
==14958==    at 0x48B8027: __vfprintf_internal (vfprintf-process-arg.c:58)
==14958==    by 0x48AD65A: printf (printf.c:33)
==14958==    by 0x109786: printArr (test.c:147)
==14958==    by 0x1093AB: main (test.c:64)
==14958== 
==14958== Conditional jump or move depends on uninitialised value(s)
==14958==    at 0x48B86F6: __vfprintf_internal (vfprintf-process-arg.c:174)
==14958==    by 0x48AD65A: printf (printf.c:33)
==14958==    by 0x109786: printArr (test.c:147)
==14958==    by 0x1093AB: main (test.c:64)
==14958== 
0 0 0 0 1 2 
3 3 4 5 6 10 
15 16 100 

==14958== Conditional jump or move depends on uninitialised value(s)
==14958==    at 0x1099BA: insertArr (test.c:192)
==14958==    by 0x109406: main (test.c:75)
==14958== 
==14958== Conditional jump or move depends on uninitialised value(s)
==14958==    at 0x1099D8: insertArr (test.c:192)
==14958==    by 0x109406: main (test.c:75)
==14958== 

1 2 3 4 5 6 
7 8 9 10 11 12 
13 14 15 1 2 3 
4 5 6 7 8 9 
10 11 12 13 14 15 
After Insert For Loop: 30 30
==14958== 
==14958== HEAP SUMMARY:
==14958==     in use at exit: 0 bytes in 0 blocks
==14958==   total heap usage: 6 allocs, 6 frees, 1,424 bytes allocated
==14958== 
==14958== All heap blocks were freed -- no leaks are possible
==14958== 
==14958== Use --track-origins=yes to see where uninitialised values come from
==14958== For lists of detected and suppressed errors, rerun with: -s
==14958== ERROR SUMMARY: 198 errors from 24 contexts (suppressed: 0 from 0)

我试图研究这个确切的问题,但我没有得到任何东西。而且其他人在回答中所说的话也并不是我真正想要的。他们的代码和答案“没有引起我的共鸣”(我什么都不懂,兄弟)。

c valgrind
1个回答
0
投票

问题是你读取了

malloc
/
realloc
之后还没有初始化的内存。这是因为您在循环中使用
arr->capacity
而不是
arr->items
(分配块中初始化的条目数)。

valgrindarr->items

 而不是 
arr->capacity
:

void insertArr(struct array *arr, int index, int item) { // for(int i = arr->items; i >= index; i--) { // not arr->capacity arr->data[i] = arr->data[i - 1]; } // }
您在

printArr

中也有同样的问题:

void printArr(struct array *arr, int limit) { // for(int i = 0; i < arr->items; i++) { // not arr->capacity // }
两次

sortArr

:

void sortArr(struct array *arr, bool reverse) { // for(int j = 0; j < (arr->items - 1 - i); j++) { // not arr->capacity // }
    
© www.soinside.com 2019 - 2024. All rights reserved.