C中的munmap_chunk错误

时间:2015-03-23 10:14:50

标签: c memory

我一直在尝试动态内存分配,我在C中遇到了munmap_chunk错误。 这是我的代码。

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

void get_input(char **input) {
  *input = (char *) malloc (100);
  *input = "hello world";
}

int main() {
  char *input;
  get_input(&input);
  puts(input);
  free(input);
  return 0;
}

这是valgrind在程序执行时显示的内容。

==4116== Memcheck, a memory error detector
==4116== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==4116== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==4116== Command: ./a.out
==4116== 
hello world
==4116== Invalid free() / delete / delete[] / realloc()
==4116==    at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4116==    by 0x400615: main (in /home/mark/Documents/CS32/a.out)
==4116==  Address 0x4006a4 is not stack'd, malloc'd or (recently) free'd
==4116== 
==4116== 
==4116== HEAP SUMMARY:
==4116==     in use at exit: 100 bytes in 1 blocks
==4116==   total heap usage: 1 allocs, 1 frees, 100 bytes allocated
==4116== 
==4116== 100 bytes in 1 blocks are definitely lost in loss record 1 of 1
==4116==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4116==    by 0x4005D2: get_input (in /home/mark/Documents/CS32/a.out)
==4116==    by 0x4005FD: main (in /home/mark/Documents/CS32/a.out)
==4116== 
==4116== LEAK SUMMARY:
==4116==    definitely lost: 100 bytes in 1 blocks
==4116==    indirectly lost: 0 bytes in 0 blocks
==4116==      possibly lost: 0 bytes in 0 blocks
==4116==    still reachable: 0 bytes in 0 blocks
==4116==         suppressed: 0 bytes in 0 blocks
==4116== 
==4116== For counts of detected and suppressed errors, rerun with: -v
==4116== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)

为什么free()函数的行为如下?另外,从valgrind日志中,为什么我的char *输入变量没有被malloc()?

分配

2 个答案:

答案 0 :(得分:1)

您可以这样分配:

*input = "hello world"; /* Not modifiable */

但是,您不需要使用malloc预留空间,"hello world"有自己的地址(在某些&#34;只读&#34;段)以及任何尝试修改字符串导致未定义的行为,因此不允许free它。

如果你想要一个可修改的字符串:

void get_input(char **input) {
    char str[] = "hello world";

    *input = malloc(sizeof(str)); /* Don't cast malloc */
    if (*input == NULL) {
        perror("malloc");
        exit(EXIT_FAILURE);
    }
    strncpy(*input, str, sizeof(str));
}

void get_input(char **input) {
    *input = strdup("hello world");
}

请注意,strdup不是标准版,但在许多实现中都可用。

答案 1 :(得分:0)

问题就在malloc之后。 (顺便说一句,不要投出malloc回归。)

*input = "hello world";

会发生什么? "hello world"告诉编译器在其中创建一些数据空间,让它称之为数据段,并插入表示字符串"hello world"的字节,包括在那里终止'\0'。然后生成代码,该代码将指向该字符串的指针插入到input指向的位置。这意味着您使之前的行代码无用。试想这两个作业一个接一个x = 1; x = 2;。这就是你刚才所做的,但x*input。 然后故事继续,您从get_input()返回并最终使用此指针指向input函数范围中变量main中的字符串。然后将其提供给free()来电。但它不是malloc()返回的指针。你失去了它。

如果您想拥有&#34; hello world&#34;在输入中你可以做

void get_input(char **input) {
  *input = (char *) malloc (100);
  strcpy(*input, "hello world");
}

int main() {
  char *input;
  get_input(&input);
  puts(input);
  free(input);
  return 0;
}

void get_input(char **input) {
  *input = "hello world";
}

int main() {
  char *input;
  get_input(&input);
  puts(input);
  return 0;
}

但现在您应该注意input指向的数据,因为它指向您无法修改的部分内存,free()realloc()。< / p>