2016-11-25 5 views
1

Вот небольшой C программа, которую я написал:Valgrind производит ошибочный вывод на моей машине

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

/* Prototypes */ 
int sum(int *summands, unsigned int n); 
void increment(char *string, int n); 
void copy(char *src, char *dst); 

int main(void) 
{ 
    int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; 
    char str1[] = "HAL"; 
    char str2[] = "SRIKANT"; 
    char str3[] = "A string to be copied."; 
    char *str4 = malloc(sizeof(str3)); 

    printf("The sum of all the elements in ARR is %d.\n", sum(arr, 9)); 

    printf("STR1 is: %s. STR2 is: %s.\n", str1, str2); 
    printf("Incrementing all letters...\n"); 
    increment(str1, 3); 
    increment(str2, 7); 
    printf("Incremented!\n"); 
    printf("STR1 is now: %s. STR2 is now: %s.\n", str1, str2); 

    copy(str3, str4); 
    printf("STR4 is: %s\n", str4); 
    free(str4); 

    return 0; 
} 

/* Returns the sum of all the elements in SUMMANDS. */ 
int sum(int *summands, unsigned int n) 
{ 
    int sum = 0; 
    for (int i = 0; i < (int) n; i++) 
    { 
     sum += *(summands + i); 
    } 
    return sum; 
} 

/* Increments all the letters in the string STRING, held in an array of length N. 
* Does not modify any other memory which has been previously allocated. */ 
void increment(char *string, int n) 
{ 
    for (int i = 0; i < n; i++) 
    { 
     (*(string + i))++; 
    } 
} 

/* Copies the string SRC to DST. */ 
// void copy(char *src, char *dst) 
// { 
//  while (*src) 
//  { 
//   *dst++ = *src++; 
//  } 
//  *dst = '\0'; 
// } 

void copy(char *src, char *dst) 
{ 
    while ((*dst++ = *src++)); 
} 

Когда я запустить исполняемый файл с Valgrind на моей машине под управлением Linux Mint 18, он производит следующий ошибочный доклад (резюме кучи) :

==5503== Memcheck, a memory error detector 
==5503== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. 
==5503== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info 
==5503== Command: ./disc1_q4 
==5503== 
The sum of all the elements in ARR is 45. 
STR1 is: HAL. STR2 is: SRIKANT. 
Incrementing all letters... 
Incremented! 
STR1 is now: IBM. STR2 is now: TSJLBOU. 
STR4 is: A string to be copied. 
==5503== 
==5503== HEAP SUMMARY: 
==5503==  in use at exit: 0 bytes in 0 blocks 
==5503== total heap usage: 2 allocs, 2 frees, 1,047 bytes allocated 
==5503== 
==5503== All heap blocks were freed -- no leaks are possible 
==5503== 
==5503== For counts of detected and suppressed errors, rerun with: -v 
==5503== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) 

Но когда я запускаю ту же программу с Valgrind на IDE Cloud 9 (который использует виртуальную машину Ubuntu), он производит правильный отчет:

==2359== Memcheck, a memory error detector 
==2359== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. 
==2359== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info 
==2359== Command: ./disc1_q4 
==2359== 
The sum of all the elements in ARR is 45. 
STR1 is: HAL. STR2 is: SRIKANT. 
Incrementing all letters... 
Incremented! 
STR1 is now: IBM. STR2 is now: TSJLBOU. 
STR4 is: A string to be copied. 
==2359== 
==2359== HEAP SUMMARY: 
==2359==  in use at exit: 0 bytes in 0 blocks 
==2359== total heap usage: 1 allocs, 1 frees, 23 bytes allocated 
==2359== 
==2359== All heap blocks were freed -- no leaks are possible 
==2359== 
==2359== For counts of detected and suppressed errors, rerun with: -v 
==2359== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) 

Почему Valgrind производит неправильные результаты на моей машине?

+0

Почему, на ваш взгляд, это ошибочно? Какое доказательство у вас есть, прежде чем обвинять вашу систему? _humans !! _ –

+0

@MichaelWalz вы уверены? –

+0

Я видел много строк, таких как 'char * str4 = malloc (sizeof (char) * (strlen (str3) + 1));', не уверен, что будет возвращать sizeof (str3), является ли это размером массива, это размер указателя символа? – Blauelf

ответ

1

Я подозреваю, что printf() выделяет память в одном случае, который вы считаете «ошибочным».

Было бы нереалистично, если бы реализация libc's printf() выделяла некоторую память внутри; это не ошибочно.

Valgrind ловит все распределения и сообщает об этом, даже если ваша программа сама не выделяет его. Вы можете проверить это, комментируя printf(). Аналогичным образом, другие стандартные функции могут также выполнять распределение памяти. Таким образом, вы не можете контролировать это, и нет «неправильного». Вам не нужно беспокоиться о «общих ассигнованиях», пока не сообщается об утечке.

+0

Что вы подразумеваете под "вашей libc' 'printf()' реализация '? Должна ли реализация 'printf()' быть одинаковой во всех ОС Linux? – SassySamurai

+0

@SassySamurai * Разве реализация printf() не должна быть одинаковой во всех ОС Linux? * - Это не обязательно; можно очень хорошо использовать другой libc, отличный от glibc. Кроме того, даже с такими же libc, но с разными версиями реализация может измениться. – usr

Смежные вопросы