So funktioniert Realloc: Übergeben Sie die Größe 0 als ArgumentLinux

Linux verstehen
Guest
 So funktioniert Realloc: Übergeben Sie die Größe 0 als Argument

Post by Guest »

Wie funktioniert Realloc, wenn die Größe 0 als Argument übergeben wird?
aus der Manpage:
Solange ptr nicht NULL ist, muss es
von an zurückgegeben worden sein früherer Aufruf von malloc(), calloc() oder realloc().
Warum muss das so sein?
Kompilieren Sie dies mit gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0 ohne Optionen (Flags)
dieses Beispiel

Code: Select all

#include 

int main () {
int *p = malloc(0);
p = realloc(p, 0);
return 0;
}
Das ist funktionierender Code. Überprüfen Sie den Speicher mit Valgrind und zeigen Sie Folgendes:

Code: Select all

valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./test
==185872== Memcheck, a memory error detector
==185872== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==185872== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==185872== Command: ./test
==185872==
==185872==
==185872== HEAP SUMMARY:
==185872==     in use at exit: 0 bytes in 0 blocks
==185872==   total heap usage: 1 allocs, 1 frees, 0 bytes allocated
==185872==
==185872== All heap blocks were freed -- no leaks are possible
==185872==
==185872== For lists of detected and suppressed errors, rerun with: -s
==185872== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from
aber kompilieren Sie dann Folgendes (Flag -g hinzugefügt):

Code: Select all

#include 

int main () {
int *p = NULL;
p = realloc(p, 0);
return 0;
}
Valgrind-Ausgabe zeigt Fehler (Speicherleck):

Code: Select all

valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./test
==186749== Memcheck, a memory error detector
==186749== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==186749== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==186749== Command: ./test
==186749==
==186749==
==186749== HEAP SUMMARY:
==186749==     in use at exit: 0 bytes in 1 blocks
==186749==   total heap usage: 1 allocs, 0 frees, 0 bytes allocated
==186749==
==186749== 0 bytes in 1 blocks are definitely lost in loss record 1 of 1
==186749==    at 0x483B723: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==186749==    by 0x483E017: realloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==186749==    by 0x10916D: main (test1.c:5)
==186749==
==186749== LEAK SUMMARY:
==186749==    definitely lost: 0 bytes in 1 blocks
==186749==    indirectly lost: 0 bytes in 0 blocks
==186749==      possibly lost: 0 bytes in 0 blocks
==186749==    still reachable: 0 bytes in 0 blocks
==186749==         suppressed: 0 bytes in 0 blocks
==186749==
==186749== For lists of detected and suppressed errors, rerun with: -s
==186749== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Warum passiert das, obwohl ich nichts zugewiesen habe?
Bearbeitungen:
habe dies mit -std=c11 -g kompiliert:

Code: Select all

#include 
#include 
#include 

#define ASSERT_ERROR_PREFIX "Assertion "
#define ASSERT_ERROR_SUFFIX " failed\n"

#define assert(x, num) { \
if(!(x)) { \
write(STDOUT_FILENO, ASSERT_ERROR_PREFIX, strlen(ASSERT_ERROR_PREFIX)); \
write(STDOUT_FILENO, num, sizeof(char)); \
write(STDOUT_FILENO, ASSERT_ERROR_SUFFIX, strlen(ASSERT_ERROR_SUFFIX)); \
} \
}

int main () {
int *p = NULL;
p = realloc(p, 0);
*p = '1';
assert((*p == '1'), "1");
assert((p == NULL), "2");
return 0;
}
Ausgabe: Behauptung 2 fehlgeschlagen
die Valgrind-Ausgabe:

Code: Select all

valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./test
==190041== Memcheck, a memory error detector
==190041== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==190041== Using Valgrind-3.15.0 and LibVEX;  rerun with -h for copyright info
==190041== Command: ./test
==190041==
==190041== Invalid write of size 4
==190041==    at 0x109196: main (test1.c:19)
==190041==  Address 0x4a5f040 is 0 bytes after a block of size 0 alloc'd
==190041==    at 0x483B723: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==190041==    by 0x483E017: realloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==190041==    by 0x10918D: main (test1.c:18)
==190041==
==190041== Invalid read of size 4
==190041==    at 0x1091A0: main (test1.c:20)
==190041==  Address 0x4a5f040 is 0 bytes after a block of size 0 alloc'd
==190041==    at 0x483B723: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==190041==    by 0x483E017: realloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==190041==    by 0x10918D: main (test1.c:18)
==190041==
Assertion 2 failed
==190041==
==190041== HEAP SUMMARY:
==190041==     in use at exit: 0 bytes in 1 blocks
==190041==   total heap usage: 1 allocs, 0 frees, 0 bytes allocated
==190041==
==190041== 0 bytes in 1 blocks are definitely lost in loss record 1 of 1
==190041==    at 0x483B723: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==190041==    by 0x483E017: realloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==190041==    by 0x10918D: main (test1.c:18)
==190041==
==190041== LEAK SUMMARY:
==190041==    definitely lost: 0 bytes in 1 blocks
==190041==    indirectly lost: 0 bytes in 0 blocks
==190041==      possibly lost: 0 bytes in 0 blocks
==190041==    still reachable: 0 bytes in 0 blocks
==190041==         suppressed: 0 bytes in 0 blocks
==190041==
==190041== For lists of detected and suppressed errors, rerun with: -s
==190041== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post