2015-11-03 168 views
1

我得到了下面的代码:我不明白为什么我得到这个错误Valgrind的

/* main.c */ 

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

int main(){ 
    int i; 
    char *msg = "This is a simple and small message"; 
    int len = strlen (msg); 
    char *new_msg = (char *) malloc (len); 
    for (i = 0; i < len; i++) 
    new_msg[i] = 'A'; 
    printf ("%s\n", new_msg); 
    free (new_msg); 
    return 0; 
} 

我编译它,然后使用Valgrind的使用下面的命令运行它:

valgrind --leak-check=full --show-reachable=yes ./main 

我得到了这个输出:

==8286== Memcheck, a memory error detector 
==8286== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. 
==8286== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info 
==8286== Command: ./main 
==8286== 
==8286== Invalid read of size 1 
==8286== at 0x4C2C1B4: strlen (vg_replace_strmem.c:412) 
==8286== by 0x4EA09FB: puts (ioputs.c:36) 
==8286== by 0x400636: main (main.c:12) 
==8286== Address 0x51de062 is 0 bytes after a block of size 34 alloc'd 
==8286== at 0x4C28C20: malloc (vg_replace_malloc.c:296) 
==8286== by 0x400601: main (main.c:9) 
==8286== 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
==8286== 
==8286== HEAP SUMMARY: 
==8286==  in use at exit: 0 bytes in 0 blocks 
==8286== total heap usage: 1 allocs, 1 frees, 34 bytes allocated 
==8286== 
==8286== All heap blocks were freed -- no leaks are possible 
==8286== 
==8286== For counts of detected and suppressed errors, rerun with: -v 
==8286== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) 

我看到所有分配的内存被释放,但我仍然得到一个我不明白的错误。

欣赏帮助。

回答

8

这是一个非常简单的错误:由于空终止符不存在,因此无效读取new_msg

您已分配的char s的数量等于原始字符串的长度,因此当前没有空间适合'\0'而没有发生未定义的行为。如下更改您的代码以解决问题:

char *new_msg = malloc (len+1); 
for (i = 0; i < len; i++) 
    new_msg[i] = 'A'; 
new_msg[len] = '\0'; 
+0

首先,感谢您的解释。现在它可以工作。其次,我看到你删除了malloc的转换。这是为什么?我在没有演员的情况下运行它,仍然得到相同的输出(即使在valgrind上)。有什么区别吗? –

+0

@mikmik [这里是关于强制'malloc'结果的一个很好的问答](http://stackoverflow.com/q/605845/335858)。不投射背后的想法是,你已经指定了类型,所以你再次重复同一段代码。演员也可以隐藏细微的错误。 – dasblinkenlight

+0

O.K.谢谢! –

1

您的代码中有很多事情需要更改。

1)len应该是size_tint,为类型size_t

2的strlen()退货)(char *) malloc (len);滴铸。这不是一个错误,虽然有理由不应该投。

3)new_msg不是NULL终止\0。这是错误发生的原因。

+1

数字1和2不是这个问题的原因。可以提及它们,但请明确区分。 – user694733

+0

@Haris演员阵容不是一个错误,而是一方面非常有用的信息,并且可以防止非正确的分配。另一方面 –

+0

@ VladfromMoscow .. donex – Haris

0

您使用strlen()来获取长度,但不包含'\ 0'。
所以当你malloc一个新的数组时,你应该使用len + 1,并且设置new_msg[len]'\0'

相关问题