mallocing char *后,为什么我仍然可以访问一个块?

时间:2015-06-13 12:09:46

标签: c parameters malloc valgrind dynamic-allocation

我有以下代码:

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>

void print_usage()
{
  printf("%s\n", "usage");
}

int file_exist (char *filename)
{
  struct stat   buffer;   
  return (stat (filename, &buffer) == 0);
}

int parse_parameters(int argc, char *argv[], char** in)
{
  unsigned int i1 = 1; // 0 is the filename
  for (; i1 < argc; ++i1)
  {
    if( 0 == strcmp("-h", argv[i1]) )
    {
      print_usage();
      return 0;
    }
    else if( 0 == strcmp("-i", argv[i1]) )
    {
      *in = malloc( sizeof(char) * strlen(argv[++i1]) + 1 );
      strcpy(*in, argv[i1]);
      continue;
    }
    else
    {
      print_usage();
      return 1;
    }
  }
  return 0;
}

int main(int argc, char *argv[])
{
  if( argc != 3 )
  {
    print_usage();
    return 0;
  }

  char* in = NULL;

  int parse = parse_parameters(argc, argv, &in);
  if ( 0 != parse )
    return parse;

  printf("in: %s\n", in);

  FILE* finput = NULL ;
  if (file_exist(in))
    finput = fopen(in, "r");
  if (finput == NULL) {
      perror("fopen");
      exit(1);
  }

  free(in);
  fclose(finput);
  return 0;
}

使用以下参数运行valgrind之后:

./main -i input

我得到以下内容:

==30977== Memcheck, a memory error detector
==30977== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==30977== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==30977== Command: ./main -i input
==30977== 
in: input
fopen: No such file or directory
==30977== 
==30977== HEAP SUMMARY:
==30977==     in use at exit: 6 bytes in 1 blocks
==30977==   total heap usage: 2 allocs, 1 frees, 574 bytes allocated
==30977== 
==30977== 6 bytes in 1 blocks are still reachable in loss record 1 of 1
==30977==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==30977==    by 0x400946: parse_parameters (main.c:31)
==30977==    by 0x4009E7: main (main.c:54)
==30977== 
==30977== LEAK SUMMARY:
==30977==    definitely lost: 0 bytes in 0 blocks
==30977==    indirectly lost: 0 bytes in 0 blocks
==30977==      possibly lost: 0 bytes in 0 blocks
==30977==    still reachable: 6 bytes in 1 blocks
==30977==         suppressed: 0 bytes in 0 blocks
==30977== 
==30977== For counts of detected and suppressed errors, rerun with: -v
==30977== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

为什么?如果我尝试将in作为char*传递,那么在parse_parameters函数后它将不会被更改。

1 个答案:

答案 0 :(得分:5)

exit (1)调用后,您的程序正在退出,该调用发生在free (in)之前。结果你看到了valgrind消息。