这是我的数和说的问题,从leetcode解决方案。但是由于内存泄漏,https://leetcode.com/problems/count-and-say/
我的制作文件
build:
gcc main.c -Wall -g -o main; \
$(PWD)/main; \我的构建命令
make
或与瓦兰:
make
valgrind --leak-check=yes ./main
输出:(正确,测试)
count and say 30 = 3113112221131112311332111213122112311311123112111331121113122112132113121113222112311311221112131221123113112221121113311211131122211211131221131211132221121321132132212321121113121112133221123113112221131112212211131221121321131211132221123113112221131112311332211211133112111311222112111312211311123113322112111312211312111322212321121113121112133221121321132132211331121321132213211231132132211211131221232112111312212221121123222112311311222113111231133211121321321122111312211312111322211213211321322123211211131211121332211231131122211311123113321112131221123113111231121123222112111331121113112221121113122113111231133221121113122113121113221112131221123113111231121123222112111312211312111322212321121113121112131112132112311321322112111312212321121113122122211211232221121321132132211331121321231231121113112221121321132132211322132113213221123113112221133112132123222112111312211312112213211231132132211211131221131211322113321132211221121332211231131122211311123113321112131221123113111231121113311211131221121321131211132221123113112211121312211231131122211211133112111311222112111312211312111322211213211321223112111311222112132113213221133122211311221122111312211312111322212321121113121112131112132112311321322112111312212321121113122122211211232221121321132132211331121321231231121113112221121321132132211322132113213221123113112221133112132123222112111312211312112213211231132132211211131221131211322113321132211221121332211213211321322113311213212312311211131122211213211331121321123123211231131122211211131221131112311332211213211321223112111311222112132113213221123123211231132132211231131122211311123113322112111312211312111322111213122112311311123112112322211213211321322113312211223113112221121113122113111231133221121321132132211331222113321112131122211332113221122112133221123113112221131112311332111213122112311311123112111331121113122112132113121113222112311311221112131221123113112221121113311211131122211211131221131211132221121321132132212321121113121112133221123113112221131112311332111213122112311311123112112322211322311311222113111231133211121312211231131112311211232221121113122113121113222123211211131221132211131221121321131211132221123113112211121312211231131122113221122112133221121321132132211331121321231231121113121113122122311311222113111231133221121113122113121113221112131221123113111231121123222112132113213221133112132123123112111312211322311211133112111312211213211311123113223112111321322123122113222122211211232221121113122113121113222123211211131211121311121321123113213221121113122123211211131221121311121312211213211321322112311311222113311213212322211211131221131211221321123113213221121113122113121113222112131112131221121321131211132221121321132132211331121321232221123113112221131112311322311211131122211213211331121321122112133221121113122113121113222123112221221321132132211231131122211331121321232221121113122113121113222123211211131211121332211213111213122112132113121113222112132113213221232112111312111213322112132113213221133112132123123112111311222112132113311213211221121332211231131122211311123113321112131221123113112221132231131122211211131221131112311332211213211321223112111311222112132113212221132221222112112322211211131221131211132221232112111312111213111213211231131112311311221122132113213221133112132123222112311311222113111231132231121113112221121321133112132112211213322112111312211312111322212321121113121112131112132112311321322112111312212321121113122122211211232221121311121312211213211312111322211213211321322123211211131211121332211213211321322113311213211322132112311321322112111312212321121113122122211211232221121321132132211331121321231231121113112221121321133112132112312321123113112221121113122113111231133221121321132122311211131122211213211321222113222122211211232221123113112221131112311332111213122112311311123112111331121113122112132113121113222112311311221112131221123113112221121113311211131122211211131221131211132221121321132132212321121113121112133221123113112221131112311332111213213211221113122113121113222112132113213221232112111312111213322112132113213221133112132123123112111312211322311211133112111312212221121123222112132113213221133112132123222113223113112221131112311332111213122112311311123112112322211211131221131211132221232112111312111213111213211231132132211211131221131211221321123113213221123113112221131112211322212322211231131122211322111312211312111322211213211321322113311213211331121113122122211211132213211231131122212322211331222113112211来自瓦兰
==1796== Memcheck, a memory error detector
==1796== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et
al.
==1796== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright
info
==1796== Command: ./main
==1796==
==1796== Invalid read of size 1
==1796== at 0x100000930: countAndSay (main.c:62)
==1796== by 0x100000ECA: main (main.c:209)
==1796== Address 0x100df6f80 is 0 bytes inside a block of size 2
free'd
==1796== at 0x1000AC2DA: realloc (vg_replace_malloc.c:829)
==1796== by 0x100000D10: countAndSay (main.c:172)
==1796== by 0x100000ECA: main (main.c:209)
==1796== Block was alloc'd at
==1796== at 0x1000AB2C5: malloc (vg_replace_malloc.c:302)
==1796== by 0x100000892: countAndSay (main.c:40)
==1796== by 0x100000ECA: main (main.c:209)
==1796==
==1796== Invalid read of size 1
==1796== at 0x10000096B: countAndSay (main.c:73)
==1796== by 0x100000ECA: main (main.c:209)
==1796== Address 0x100df6f80 is 0 bytes inside a block of size 2
free'd
==1796== at 0x1000AC2DA: realloc (vg_replace_malloc.c:829)
==1796== by 0x100000D10: countAndSay (main.c:172)
==1796== by 0x100000ECA: main (main.c:209)
==1796== Block was alloc'd at
==1796== at 0x1000AB2C5: malloc (vg_replace_malloc.c:302)
==1796== by 0x100000892: countAndSay (main.c:40)
==1796== by 0x100000ECA: main (main.c:209)
==1796==
==1796== Invalid read of size 1
==1796== at 0x1000009D7: countAndSay (main.c:89)
==1796== by 0x100000ECA: main (main.c:209)
==1796== Address 0x100df6f80 is 0 bytes inside a block of size 2
free'd
==1796== at 0x1000AC2DA: realloc (vg_replace_malloc.c:829)
==1796== by 0x100000D10: countAndSay (main.c:172)
==1796== by 0x100000ECA: main (main.c:209)
==1796== Block was alloc'd at
==1796== at 0x1000AB2C5: malloc (vg_replace_malloc.c:302)
==1796== by 0x100000892: countAndSay (main.c:40)
==1796== by 0x100000ECA: main (main.c:209)
==1796==
==1796== Invalid read of size 16
==1796== at 0x100655A65: _platform_memchr$VARIANT$Base (in
/usr/lib/system/libsystem_platform.dylib)
==1796== by 0x1002E99E9: __sfvwrite (in
/usr/lib/system/libsystem_c.dylib)
==1796== by 0x1002F35FE: __vfprintf (in
/usr/lib/system/libsystem_c.dylib)
==1796== by 0x100318058: __v2printf (in
/usr/lib/system/libsystem_c.dylib)
==1796== by 0x1002EF741: vfprintf_l (in
/usr/lib/system/libsystem_c.dylib)
==1796== by 0x1002ED7CA: printf (in
/usr/lib/system/libsystem_c.dylib)
==1796== by 0x100000EE0: main (main.c:210)
==1796== Address 0x10545d410 is 1 bytes after a block of size 4,463
alloc'd
==1796== at 0x1000AB2C5: malloc (vg_replace_malloc.c:302)
==1796== by 0x1000AC30C: realloc (vg_replace_malloc.c:829)
==1796== by 0x100000C67: countAndSay (main.c:157)
==1796== by 0x100000ECA: main (main.c:209)
==1796==
==1796== Conditional jump or move depends on uninitialised value(s)
==1796== at 0x100655A7D: _platform_memchr$VARIANT$Base (in
/usr/lib/system/libsystem_platform.dylib)
==1796== by 0x1002E99E9: __sfvwrite (in
/usr/lib/system/libsystem_c.dylib)
==1796== by 0x1002F35FE: __vfprintf (in
/usr/lib/system/libsystem_c.dylib)
==1796== by 0x100318058: __v2printf (in
/usr/lib/system/libsystem_c.dylib)
==1796== by 0x1002EF741: vfprintf_l (in
/usr/lib/system/libsystem_c.dylib)
==1796== by 0x1002ED7CA: printf (in
/usr/lib/system/libsystem_c.dylib)
==1796== by 0x100000EE0: main (main.c:210)
==1796==
count and say 30 = 3113112221131112311332111213122112311311123112111331121113122112132113121113222112311311221112131221123113112221121113311211131122211211131221131211132221121321132132212321121113121112133221123113112221131112212211131221121321131211132221123113112221131112311332211211133112111311222112111312211311123113322112111312211312111322212321121113121112133221121321132132211331121321132213211231132132211211131221232112111312212221121123222112311311222113111231133211121321321122111312211312111322211213211321322123211211131211121332211231131122211311123113321112131221123113111231121123222112111331121113112221121113122113111231133221121113122113121113221112131221123113111231121123222112111312211312111322212321121113121112131112132112311321322112111312212321121113122122211211232221121321132132211331121321231231121113112221121321132132211322132113213221123113112221133112132123222112111312211312112213211231132132211211131221131211322113321132211221121332211231131122211311123113321112131221123113111231121113311211131221121321131211132221123113112211121312211231131122211211133112111311222112111312211312111322211213211321223112111311222112132113213221133122211311221122111312211312111322212321121113121112131112132112311321322112111312212321121113122122211211232221121321132132211331121321231231121113112221121321132132211322132113213221123113112221133112132123222112111312211312112213211231132132211211131221131211322113321132211221121332211213211321322113311213212312311211131122211213211331121321123123211231131122211211131221131112311332211213211321223112111311222112132113213221123123211231132132211231131122211311123113322112111312211312111322111213122112311311123112112322211213211321322113312211223113112221121113122113111231133221121321132132211331222113321112131122211332113221122112133221123113112221131112311332111213122112311311123112111331121113122112132113121113222112311311221112131221123113112221121113311211131122211211131221131211132221121321132132212321121113121112133221123113112221131112311332111213122112311311123112112322211322311311222113111231133211121312211231131112311211232221121113122113121113222123211211131221132211131221121321131211132221123113112211121312211231131122113221122112133221121321132132211331121321231231121113121113122122311311222113111231133221121113122113121113221112131221123113111231121123222112132113213221133112132123123112111312211322311211133112111312211213211311123113223112111321322123122113222122211211232221121113122113121113222123211211131211121311121321123113213221121113122123211211131221121311121312211213211321322112311311222113311213212322211211131221131211221321123113213221121113122113121113222112131112131221121321131211132221121321132132211331121321232221123113112221131112311322311211131122211213211331121321122112133221121113122113121113222123112221221321132132211231131122211331121321232221121113122113121113222123211211131211121332211213111213122112132113121113222112132113213221232112111312111213322112132113213221133112132123123112111311222112132113311213211221121332211231131122211311123113321112131221123113112221132231131122211211131221131112311332211213211321223112111311222112132113212221132221222112112322211211131221131211132221232112111312111213111213211231131112311311221122132113213221133112132123222112311311222113111231132231121113112221121321133112132112211213322112111312211312111322212321121113121112131112132112311321322112111312212321121113122122211211232221121311121312211213211312111322211213211321322123211211131211121332211213211321322113311213211322132112311321322112111312212321121113122122211211232221121321132132211331121321231231121113112221121321133112132112312321123113112221121113122113111231133221121321132122311211131122211213211321222113222122211211232221123113112221131112311332111213122112311311123112111331121113122112132113121113222112311311221112131221123113112221121113311211131122211211131221131211132221121321132132212321121113121112133221123113112221131112311332111213213211221113122113121113222112132113213221232112111312111213322112132113213221133112132123123112111312211322311211133112111312212221121123222112132113213221133112132123222113223113112221131112311332111213122112311311123112112322211211131221131211132221232112111312111213111213211231132132211211131221131211221321123113213221123113112221131112211322212322211231131122211322111312211312111322211213211321322113311213211331121113122122211211132213211231131122212322211331222113112211
==1796==
==1796== HEAP SUMMARY:
==1796== in use at exit: 29,301,895 bytes in 40,712 blocks
==1796== total heap usage: 80,412 allocs, 39,700 frees, 58,326,719
bytes allocated
==1796==
==1796== 72 bytes in 3 blocks are possibly lost in loss record 25 of 51
==1796== at 0x1000ABD72: calloc (vg_replace_malloc.c:755)
==1796== by 0x10075A7C2: map_images_nolock (in
/usr/lib/libobjc.A.dylib)
==1796== by 0x10076D4E0: map_images (in /usr/lib/libobjc.A.dylib)
==1796== by 0x100007C64: dyld::notifyBatchPartial(dyld_image_states,
bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info
const*), bool, bool) (in /usr/lib/dyld)
==1796== by 0x100007E39: dyld::registerObjCNotifiers(void (*)
(unsigned int, char const* const*, mach_header const* const*), void (*)
(char const*, mach_header const*), void (*)(char const*, mach_header
const*)) (in /usr/lib/dyld)
==1796== by 0x10022571D: _dyld_objc_notify_register (in /
/usr/lib/system/libdyld.dylib)
==1796== by 0x10075A073: _objc_init (in /usr/lib/libobjc.A.dylib)
==1796== by 0x1001AFB34: _os_object_init (in
/usr/lib/system/libdispatch.dylib)
==1796== by 0x1001AFB1B: libdispatch_init (in
/usr/lib/system/libdispatch.dylib)
==1796== by 0x1000BE9C2: libSystem_initializer (in
/usr/lib/libSystem.B.dylib)
==1796== by 0x100019AC5:
ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&)
(in /usr/lib/dyld)
==1796== by 0x100019CF5:
ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in
/usr/lib/dyld)
==1796==
==1796== 168 bytes in 56 blocks are definitely lost in loss record 28
of 51
==1796== at 0x1000AB2C5: malloc (vg_replace_malloc.c:302)
==1796== by 0x1000AC30C: realloc (vg_replace_malloc.c:829)
==1796== by 0x100000D10: countAndSay (main.c:172)
==1796== by 0x100000ECA: main (main.c:209)
==1796==
==1796== 570 bytes in 1 blocks are possibly lost in loss record 37 of
51
==1796== at 0x1000AC2DA: realloc (vg_replace_malloc.c:829)
==1796== by 0x100000DCD: countAndSay (main.c:184)
==1796== by 0x100000ECA: main (main.c:209)
==1796==
==1796== 1,512 bytes in 378 blocks are definitely lost in loss record
38 of 51
==1796== at 0x1000AB2C5: malloc (vg_replace_malloc.c:302)
==1796== by 0x1000AC30C: realloc (vg_replace_malloc.c:829)
==1796== by 0x100000DCD: countAndSay (main.c:184)
==1796== by 0x100000ECA: main (main.c:209)
==1796==
==1796== 4,462 bytes in 1 blocks are definitely lost in loss record 45
of 51
==1796== at 0x1000AB2C5: malloc (vg_replace_malloc.c:302)
==1796== by 0x100000867: countAndSay (main.c:29)
==1796== by 0x100000ECA: main (main.c:209)
==1796==
==1796== 17,848 bytes in 1 blocks are definitely lost in loss record 46
of 51
==1796== at 0x1000AB2C5: malloc (vg_replace_malloc.c:302)
==1796== by 0x100000857: countAndSay (main.c:28)
==1796== by 0x100000ECA: main (main.c:209)
==1796==
==1796== 19,257 (240 direct, 19,017 indirect) bytes in 1 blocks are d
definitely lost in loss record 48 of 51
==1796== at 0x1000AB2C5: malloc (vg_replace_malloc.c:302)
==1796== by 0x100000839: countAndSay (main.c:19)
==1796== by 0x100000ECA: main (main.c:209)
==1796==
==1796== 61,644 bytes in 406 blocks are definitely lost in loss record
49 of 51
==1796== at 0x1000AB2C5: malloc (vg_replace_malloc.c:302)
==1796== by 0x1000AC30C: realloc (vg_replace_malloc.c:829)
==1796== by 0x100000C67: countAndSay (main.c:157)
==1796== by 0x100000ECA: main (main.c:209)
==1796==
==1796== 80,493 bytes in 379 blocks are definitely lost in loss record
50 of 51
==1796== at 0x1000AC2DA: realloc (vg_replace_malloc.c:829)
==1796== by 0x100000D10: countAndSay (main.c:172)
==1796== by 0x100000ECA: main (main.c:209)
==1796==
==1796== 29,093,648 bytes in 39,299 blocks are definitely lost in loss
record 51 of 51
==1796== at 0x1000AC2DA: realloc (vg_replace_malloc.c:829)
==1796== by 0x100000DCD: countAndSay (main.c:184)
==1796== by 0x100000ECA: main (main.c:209)
==1796==
==1796== LEAK SUMMARY:
==1796== definitely lost: 29,260,015 bytes in 40,521 blocks
==1796== indirectly lost: 19,017 bytes in 29 blocks
==1796== possibly lost: 642 bytes in 4 blocks
==1796== still reachable: 200 bytes in 6 blocks
==1796== suppressed: 22,021 bytes in 152 blocks
==1796== Reachable blocks (those to which a pointer was found) are not
shown.
==1796== To see them, rerun with: --leak-check=full --show-leak-
kinds=all
==1796==
==1796== For counts of detected and suppressed errors, rerun with: -v
==1796== Use --track-origins=yes to see where uninitialised values come
from
==1796== ERROR SUMMARY: 124 errors from 15 contexts (suppressed: 11
from 11)main.c
#include <stdio.h>
#include <stdlib.h>
#define MAX_SEQUENCE_COUNT 30
#define BUFFER_MAX 4462
char* countAndSay(int n) {
int msc;
if (n > 0 && n <= 30) {
msc = MAX_SEQUENCE_COUNT;
} else {
fprintf(stderr, "Error: The range for this count and say method is 1...30\n");
exit(1);
}
//Holds the array of sequences
char **out_buffer = malloc(msc * sizeof(char*));
//Holds current sequence
char *out;
int size = n;
//Holds previous sequence
char *prev_chunk = NULL;
//memory for the counts and says
int *counts = malloc(BUFFER_MAX*sizeof(int));
char *says = malloc(BUFFER_MAX*sizeof(char));
//index into the buffer memory of sequences
int index = 0;
//solve iteratively
while (size > 0) {
//base condition
//size counts down to 0, filling chunks, populating the next chunk to be processed
//filled chunks are placed in the out buffer at the index which is counting
if (index == 0) {
out = malloc(2 * sizeof(char));
out[0] = '1';
out[1] = '\0';
prev_chunk = out;
size -= 1;
index += 1;
out_buffer[0] = out;
continue;
}
//from 0 to index - 1 get the chunk to be processed, use it to put together
//the count and say chunk for adding to the index slot
for (int s = 0; s < index; s++) {
if (s == 0) {
prev_chunk = out_buffer[0];
} else {
prev_chunk = out_buffer[index];
}
//count the length of the current chunk
int length = 0;
for (int e = 0; e <= BUFFER_MAX; e++) {
if (prev_chunk[e]) {
length += 1;
} else {
break;
}
}
//The count of says at each iteration
int count = 0;
//say is a char byte from the previous chunk memory
char say = prev_chunk[0];
//skip is used in the iteration process
int skip = 0;
//The idx into memory for the counts and says
int idx = 0;
//iteratively generate the count and say chunk for this index
for (int i = 0; i < length; i++) {
if (skip > 0) {
if (i < length - 1) {
say = prev_chunk[i + 1];
}
skip -= 1;
continue;
}
if (prev_chunk[i] == say) {
count += 1;
counts[idx] = count;
says[idx] = say;
//if at the end of the iteration add one
//as a terminator for the counts, says, pairs
if (i == length - 1) {
idx += 1;
break;
}
} else {
count = 0;
if (i == length - 1) {
//finish off
idx += 1;
count += 1;
counts[idx] = count;
says[idx] = prev_chunk[i];
say = says[idx];
idx += 1;
} else {
idx += 1;
count += 1;
counts[idx] = count;
says[idx] = prev_chunk[i];
char next_say = prev_chunk[i + 1];
say = prev_chunk[i];
//Takes care of itself with idx
if (next_say != prev_chunk[i]) {
count = 0;
continue;
}
int y = i;
while (next_say == say && y < length -1) {
count += 1;
//dont need to up the index because we are counting howmany there are
says[idx] = say;
counts[idx] = count;
//skip because this is the next loop
skip += 1;
//subtract 1 because we want this to be in the final index slot
//count because we added an index
y += 1;
next_say = prev_chunk[y + 1];
}
idx += 1;
count = 0;
}
}
}
//Could have just generated the sequence from above but felt like doing this manually at the time
//If I get around to it ill change
int chunk_offset = 0;
char *temp = NULL;
for (int u = 0; u < idx; u++) {
int c = counts[u];
//TODO: factor out or use sprintf, or maybe not, maybe this is just faster
char cc;
if (c >= 10) {
cc = 'A' + c - 10;
} else {
cc = '0' + c;
}
char say = says[u];
if (u == idx - 1) {
temp = realloc(temp, chunk_offset + 3);
if (chunk_offset > 0) {
for (int y = 0; y < chunk_offset; y++) {
temp[y] = out[y];
}
temp[chunk_offset] = cc;
temp[chunk_offset + 1] = say;
temp[chunk_offset + 2] = '\0';
} else {
temp[0] = cc;
temp[1] = say;
temp[2] = '\0';
}
out = realloc(out, chunk_offset + 3);
out = temp;
temp = NULL;
free(temp);
} else {
temp = realloc(temp, chunk_offset + 2);
for (int ii = 0; ii < chunk_offset; ii++) {
temp[ii] = out[ii];
}
temp[chunk_offset] = cc;
temp[chunk_offset + 1] = say;
chunk_offset += 2;
out = realloc(out, chunk_offset + 2);
out = temp;
temp = NULL;
free(temp);
}
}
out_buffer[index] = out;
out = NULL;
free(out);
}
index += 1;
size -= 1;
}
free(prev_chunk);
prev_chunk = NULL;
free(counts);
counts = NULL;
free(says);
says = NULL;
return out_buffer[n - 1];
}
int main(int argc, char **argv) {
char *cs = countAndSay(30);
printf("count and say 30 = %s\n", cs);
}我知道这不是最好的算法,但它有效。据我理解,realloc可以避免将malloc内存堆积到循环内部的堆中,就像这样。我怀疑这样做会把记忆转移到不易发现和自由的地方。我是否走上了正确的道路?简单现实
char *e = NULL;
for (int i = 0; i < 10; i++) {
e = realloc(e, i + 1);
if (i == 9) {
e[i] = '\0';
} else {
e[i] = 'e';
}
}
printf("%s\n", e);
free(e);缬草的产量:
==4421== LEAK SUMMARY:
==4421== definitely lost: 0 bytes in 0 blocks
==4421== indirectly lost: 0 bytes in 0 blocks
==4421== possibly lost: 72 bytes in 3 blocks
==4421== still reachable: 200 bytes in 6 blocks
==4421== suppressed: 22,021 bytes in 152 blocks我一直在用勇敢的方法处理这件事,试图找出漏水的问题。我也看到了这样的解决方案,并没有成功地尝试过:“未分配被释放的指针。”在malloc、realloc之后出错。
我相信我在这里遇到的主要问题是我第一次“退出”。在那之后,我每次都在循环中重新分配它。main.c:184行的最大漏洞是"out = realloc(out,chunk_offset + 2);“。看起来,realloc只是决定将内存放在堆中的某个地方,而我无法理解它。我知道地址可能会改变,但我仍然无法得到它。在我的数中,我怎么会迷失到0呢?
发布于 2019-01-08 19:31:39
让我们从这个块开始:
if (u == idx - 1) {
temp = realloc(temp, chunk_offset + 3);
if (chunk_offset > 0) {
for (int y = 0; y < chunk_offset; y++) {
temp[y] = out[y];
}
temp[chunk_offset] = cc;
temp[chunk_offset + 1] = say;
temp[chunk_offset + 2] = '\0';
} else {
temp[0] = cc;
temp[1] = say;
temp[2] = '\0';
}
out = realloc(out, chunk_offset + 3);
// *** MEMORY LEAK ***
out = temp;
temp = NULL;
// NOT NEEDED
free(temp);
} else {
temp = realloc(temp, chunk_offset + 2);
for (int ii = 0; ii < chunk_offset; ii++) {
temp[ii] = out[ii];
}
temp[chunk_offset] = cc;
temp[chunk_offset + 1] = say;
chunk_offset += 2;
out = realloc(out, chunk_offset + 2);
// *** MEMORY LEAK ***
out = temp;
temp = NULL;
// NOT NEEDED
free(temp);
}在if的两个部分中,您都扩展了out的大小,但是随后您立即用temp的值覆盖了out,泄漏了out所指向的内存。
由于temp包含您想要的值,您不再需要out中的内容,所以不要使用out上的realloc,而是使用以前的free。而且,没有必要使用free(temp),因为它指向NULL,您可以用malloc替换realloc调用,因为temp在这一点上总是为NULL:
if (u == idx - 1) {
temp = malloc(chunk_offset + 3);
if (chunk_offset > 0) {
for (int y = 0; y < chunk_offset; y++) {
temp[y] = out[y];
}
temp[chunk_offset] = cc;
temp[chunk_offset + 1] = say;
temp[chunk_offset + 2] = '\0';
} else {
temp[0] = cc;
temp[1] = say;
temp[2] = '\0';
}
} else {
temp = malloc(chunk_offset + 2);
for (int ii = 0; ii < chunk_offset; ii++) {
temp[ii] = out[ii];
}
temp[chunk_offset] = cc;
temp[chunk_offset + 1] = say;
chunk_offset += 2;
}
free(out);
out = temp;然后,在您的for循环的底部有以下内容:
for (int s = 0; s < index; s++) {
...
out_buffer[index] = out;
out = NULL;
free(out);
}您将在每次迭代中覆盖out_buffer[index]的内容,从而泄漏内存。您需要首先对旧内容进行free,并在结束时去掉不需要的free(out),因为在这一点上它包含NULL。这也意味着您需要在进入循环之前将out_buffer[index]初始化为NULL。
out_buffer[index] = NULL;
for (int s = 0; s < index; s++) {
...
free(out_buffer[index]);
out_buffer[index] = out;
out = NULL;
}那么你在这里有个问题:
if (index == 0) {
out = malloc(2 * sizeof(char));
out[0] = '1';
out[1] = '\0';
prev_chunk = out;
size -= 1;
index += 1;
out_buffer[0] = out;
continue;
}它无法在循环的下一次迭代之前将out设置为NULL,这将导致out_buffer[0]获得空闲“‘ed”,并随后从空闲的’ed内存中读取。因此,在这里补充一下:
if (index == 0) {
out = malloc(2 * sizeof(char));
out[0] = '1';
out[1] = '\0';
prev_chunk = out;
size -= 1;
index += 1;
out_buffer[0] = out;
out = NULL;
continue;
}最后:
free(prev_chunk);
prev_chunk = NULL;
free(counts);
counts = NULL;
free(says);
says = NULL;
return out_buffer[n - 1];您不想使用free(prev_chunk);,因为它指向一个已经免费的out的旧副本。您也没有释放out_buffer或它所指向的任何字符串。当然,您不想释放返回的字符串,所以跳过这个字符串:
char *rval = out_buffer[n - 1];
for (int i = 0; i < n - 1; i++) {
free(out_buffer[i]);
}
free(out_buffer);
free(counts);
free(says);
return rval;最后,确保一旦使用free完成了main,就会得到这个函数的结果:
char *cs = countAndSay(30);
printf("count and say 30 = %s\n", cs);
free(cs);现在,您有了一个干净的运行过程,没有内存泄漏,也没有无效的读/写/释放错误。
顺便提一句,这段代码中有很多效率低下的地方。在外部while循环的每次迭代中,从n的1到当前值生成整个列表。因此,在第一次迭代中计算n=1,然后在下一次迭代中计算n=1,2,然后在下一次迭代中计算n=1,2,3,等等。
这里只需要一个循环。这也意味着您不必重用out_buffer的当前值,而只需引用前一个值即可。我将把这些修改留给读者来做练习。
发布于 2019-01-05 22:55:17
您的问题是,您正在释放在循环结束时分配的指针,即使您将指针保存为后代或其他东西。
基于这段代码,我想说你想做几件事:
=gg来重新格式化一切,使其变得合理。(注意:如果您不使用vi、nvi或vim,不要仅仅因为我使用它而使用它--所有这三个编辑器都有一个巨大的学习曲线,而且大多数编程编辑器都可以做同样的事情。)为了强调最后一点:一旦我把它修改成有一致的缩进,问题就跳出了我的心头。汤姆差一点就明白了,但我想他认为这是你的功能的终结,而不是你循环的结束。
https://stackoverflow.com/questions/54056875
复制相似问题