我不太確定為什么會這樣,但在下面的代碼中,我撰寫了一個簡單的程式來幫助我理解 malloc 的作業原理。我基本上是想看看如何根據記憶體地址調整陣列大小。
#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;
}
但是當我運行它時,realloc 回傳 NULL。在這里,它與 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)
據我所知,字串是 malloc 的,而且我之前肯定沒有釋放它。那么,這里發生了什么?
uj5u.com熱心網友回復:
這里:
buff = malloc(10);
buff = "hi";
您重新分配了保存在buff...中的地址
你可能的意思是:
strcpy( buff, "hi" );
realloc()而且,如果該函式已重新定位您的資料以增大/縮小緩沖區,您需要捕獲回傳的指標。
此外,始終檢查任何系統呼叫的回傳碼。您可能會測驗是否fopen()回傳 NULL。好吧,記憶體分配也可能失敗!
char *buff = malloc( 10 );
if( buff == NULL ) {
fprintf( stderr, "malloc failed\n" );
exit( EXIT_FAILURE ); // probably not going to get much further
}
編輯:那太容易了。這是一個帶注釋的版本(省略拼寫錯誤)應該顯示您應該/可以如何使用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;
}
警告:這取決于您,即“保留”堆記憶體塊的程式員,來跟蹤該塊有多大,而不是在該操場之外“亂涂亂畫”。free()會做正確的事情,但是在malloc()and之間free(),并且變得更加復雜,realloc()因為有很多機會超出緩沖區并呼叫“未定義的行為”。
更進一步……
事實上,在某些情況下,當代碼接收到 NULL 作為第一個引數時,只 realloc()使用“行為類似于”會更好......malloc()
#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;
}
輸出
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
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/510573.html
