[英]realloc not working despite using it on a malloc'ed string
I'm not really sure why this is happening but in the code below I made a simple program to help me understand how malloc works.我不太确定为什么会发生这种情况,但在下面的代码中,我编写了一个简单的程序来帮助我了解 malloc 的工作原理。 I was basically trying to see how resizing arrays works in term of memory addresses.
我基本上是想看看如何根据 memory 地址调整 arrays 的大小。
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char *argv[])
{
char* buff;
buff = malloc(10);
buff = "hi";
printf("%c\n", buff[0]);
printf("%p\n", &buff[0]);
if (realloc(buff, (size_t) 20) == NULL){
printf("no\n");
exit(1);
}
printf("%p\n", &buff[0]);
return 0;
}
But when I run it, realloc returns NULL.但是当我运行它时,realloc 返回 NULL。 Here it is running with valgrind.
在这里,它与 valgrind 一起运行。
valgrind ./test
==3421== Memcheck, a memory error detector
==3421== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==3421== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==3421== Command: ./test
==3421==
h
0x400734
==3421== Invalid free() / delete / delete[] / realloc()
==3421== at 0x4C2CE8E: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3421== by 0x400673: main (in /home/puf311/cs3733/practice/test)
==3421== Address 0x400734 is not stack'd, malloc'd or (recently) free'd
==3421==
no==3421==
==3421== HEAP SUMMARY:
==3421== in use at exit: 10 bytes in 1 blocks
==3421== total heap usage: 2 allocs, 1 frees, 15 bytes allocated
==3421==
==3421== LEAK SUMMARY:
==3421== definitely lost: 10 bytes in 1 blocks
==3421== indirectly lost: 0 bytes in 0 blocks
==3421== possibly lost: 0 bytes in 0 blocks
==3421== still reachable: 0 bytes in 0 blocks
==3421== suppressed: 0 bytes in 0 blocks
==3421== Rerun with --leak-check=full to see details of leaked memory
==3421==
==3421== For counts of detected and suppressed errors, rerun with: -v
==3421== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
As far as I know, the string is malloc'ed, and I definitely didn't free it earlier.据我所知,字符串是 malloc 的,而且我之前肯定没有释放它。 So, what's going on here?
那么,这里发生了什么?
Here:这里:
buff = malloc(10);
buff = "hi";
You've reassigned the address held in buff
...您已经重新分配了
buff
中保存的地址...
You probably meant:你可能的意思是:
strcpy( buff, "hi" );
And, you need to capture the returned pointer from realloc()
in case that function has relocated your data to grow/shrink the buffer.而且,您需要从
realloc()
捕获返回的指针,以防 function 已重新定位您的数据以增大/缩小缓冲区。
Further, ALWAYS check return codes from any system call.此外,始终检查任何系统调用的返回码。 You probably test if
fopen()
returned NULL.您可能会测试
fopen()
是否返回 NULL。 Well, memory allocation can fail, too!好吧,memory 分配也可能失败!
char *buff = malloc( 10 );
if( buff == NULL ) {
fprintf( stderr, "malloc failed\n" );
exit( EXIT_FAILURE ); // probably not going to get much further
}
EDIT: That was too easy.编辑:那太容易了。 Here's an annotated version that (omitting typos) should show how you should/could use
realloc()
这是一个带注释的版本(省略拼写错误)应该显示您应该/可以如何使用
realloc()
int main() {
char *buff = malloc( 10 );
if( buff == NULL ) {
fprintf( stderr, "Failed to launch!\n" );
exit( EXIT_FAILURE );
}
strcpy( buff, "hi" ); // should fit!
puts( buff ); // working???
printf( "%c\n", buff[0] ); // should be 'h'
printf( "%p\n", &buff[0] ); // should be the same as...
printf( "%p\n", buff ); // this
{ // NB: 'tmp' is only within the 'scope' of this pair of braces
char *tmp = realloc( buff, 20 ); // delicately
if ( tmp == NULL ) {
// Here it is, but this need not be a "hard error"
// Report problem, but could perhaps continue with same sized buffer, somehow...
fprintf( stderr, "Cannot grow the buffer, but,,, ");
printf( "still have '%s' and 'Good-bye'\n", buff );
free( buff );
exit( EXIT_FAILURE);
}
buff = tmp; // Got it. (Don't replace if "soft error" of tmp being NULL, of course)
}
printf( "%p\n", buff ); // just to see if block relocated
free( buff ); // don't forget about this
return 0;
}
Caveat: It's up to you, the programmer who 'reserves' blocks of heap memory, to track how big that block is and not "scribble" outside of that playground.警告:这取决于你,“保留”堆 memory 块的程序员,来跟踪那个块有多大,而不是在那个操场之外“乱涂乱画”。
free()
will do the right thing, but between malloc()
and free()
, and made more complex with realloc()
there is a lot of opportunity to overrun the buffer and invoke "undefined behaviour". free()
会做正确的事情,但是在malloc()
和free()
之间,并且使用realloc()
变得更加复杂,有很多机会超出缓冲区并调用“未定义的行为”。
Taking this one step further...更进一步……
In fact, on some occasions the code is better using only realloc()
that "acts like malloc()
" when it receives a NULL as the first parameter...事实上,在某些情况下,当代码接收 NULL 作为第一个参数时,只使用“行为类似于
malloc()
”的realloc()
会更好......
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char sentence[] = "The quick brown fox jumps over the lazy dog";
char **words = NULL;
// Chop up a mutable string (sentence), isolating each word
// accessible via its own pointer.
// realloc() "grows" the array of pointers to words.
int i = 0;
for( char *p = sentence; (p = strtok( p, " " )) != NULL; p = NULL ) {
char **tmp = realloc( words, (i+1) * sizeof *tmp );
if ( tmp == NULL ) {
fprintf( stderr, "realloc failed on %d - %s\n", i, p );
free( words );
exit( EXIT_FAILURE);
}
words = tmp;
words[ i++ ] = p;
printf( "cnt(%d) ", i ); // debugging
}
putchar( '\n' ); // debugging
while( i-- ) // reverse order
puts( words[i] );
free( words );
return 0;
}
Output Output
cnt(1) cnt(2) cnt(3) cnt(4) cnt(5) cnt(6) cnt(7) cnt(8) cnt(9)
dog
lazy
the
over
jumps
fox
brown
quick
The
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.