大小为8、C、字符串数组的写入无效
我一直在使用valgrind和gdb,我不太明白问题出在哪里。它跳得太多了,我无法在gdb中找到它,而在valgrind中我没有足够的信息。这是我的makeargv函数,它将从strtok()输出的字符串放入数组。makeargv是从下面的解析函数调用的。我不确定我错在哪里。我非常感谢你的帮助:D 仅供参考,我对这一切都很陌生,并不像我想的那样理解这个概念。我不确定具体什么时候我应该去mallocing。我觉得既然我在这里主要是设置常量值,我不必这样,但我想知道为什么它不起作用 makeargv函数大小为8、C、字符串数组的写入无效,c,arrays,segmentation-fault,malloc,valgrind,C,Arrays,Segmentation Fault,Malloc,Valgrind,我一直在使用valgrind和gdb,我不太明白问题出在哪里。它跳得太多了,我无法在gdb中找到它,而在valgrind中我没有足够的信息。这是我的makeargv函数,它将从strtok()输出的字符串放入数组。makeargv是从下面的解析函数调用的。我不确定我错在哪里。我非常感谢你的帮助:D 仅供参考,我对这一切都很陌生,并不像我想的那样理解这个概念。我不确定具体什么时候我应该去mallocing。我觉得既然我在这里主要是设置常量值,我不必这样,但我想知道为什么它不起作用 makeargv
int makeargv(const char *string, char **argvp) {
int i = 0;
int numtokens = 0;
const char *copy;
char *buffer = malloc(160*sizeof(char));
if ((string == NULL) || (delims == NULL) || (argvp == NULL)) {
return -1;
}
argvp = NULL;
copy = string + strspn(string, delims);
if ((buffer = malloc(strlen(copy) + 1)) == NULL) {
return -1;
}
strcpy(buffer, copy);
numtokens = 0;
if (strtok(buffer, delims) != NULL) {
for (numtokens = 1; strtok(NULL, delims) != NULL; numtokens++);
}
if ((argvp = malloc((numtokens + 2)*sizeof(int))) == NULL) {
free(buffer);
return -1;
}
if (numtokens == 0) {
free(buffer);
}
else {
strcpy(buffer, copy);
*argvp = malloc(16);
*argvp = strtok(buffer, delims);
for (i = 2; i < (numtokens*2); i += 2) {
*(argvp + i) = strtok(NULL, delims);
//printf("%s\n", strtok(NULL, delims)); /*When I run this the tokens come out
correctly so I know it isn't a problem with strtok */
}
}
// *((argvp) + numtokens) = NULL;
free(buffer);
return numtokens;
}
瓦尔研磨输出
==7309== Memcheck, a memory error detector
==7309== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==7309== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==7309== Command: ./custmake
==7309==
==7309== Invalid write of size 8
==7309== at 0x400C23: makeargv (main.c:62)
==7309== by 0x400CD4: parse_file (main.c:120)
==7309== by 0x400DFF: main (main.c:172)
==7309== Address 0x51f25c0 is 16 bytes inside a block of size 20 alloc'd
==7309== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7309== by 0x400B76: makeargv (main.c:49)
==7309== by 0x400CD4: parse_file (main.c:120)
==7309== by 0x400DFF: main (main.c:172)
==7309==
==7309== Use of uninitialised value of size 8
==7309== at 0x4C2BFC2: __GI_strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7309== by 0x4EA2CEB: puts (ioputs.c:37)
==7309== by 0x400D09: parse_file (main.c:128)
==7309== by 0x400DFF: main (main.c:172)
==7309==
==7309== Invalid read of size 1
==7309== at 0x4C2BFC2: __GI_strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7309== by 0x4EA2CEB: puts (ioputs.c:37)
==7309== by 0x400D09: parse_file (main.c:128)
==7309== by 0x400DFF: main (main.c:172)
==7309== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==7309==
==7309==
==7309== Process terminating with default action of signal 11 (SIGSEGV)
==7309== Access not within mapped region at address 0x0
==7309== at 0x4C2BFC2: __GI_strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7309== by 0x4EA2CEB: puts (ioputs.c:37)
==7309== by 0x400D09: parse_file (main.c:128)
==7309== by 0x400DFF: main (main.c:172)
==7309== If you believe this happened as a result of a stack
==7309== overflow in your program's main thread (unlikely but
==7309== possible), you can try to increase the size of the
==7309== main thread stack using the --main-stacksize= flag.
==7309== The main thread stack size used in this run was 8388608.
==7309==
==7309== HEAP SUMMARY:
==7309== in use at exit: 1,084 bytes in 6 blocks
==7309== total heap usage: 7 allocs, 1 frees, 1,100 bytes allocated
==7309==
==7309== 16 bytes in 1 blocks are definitely lost in loss record 1 of 6
==7309== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7309== by 0x400BCB: makeargv (main.c:59)
==7309== by 0x400CD4: parse_file (main.c:120)
==7309== by 0x400DFF: main (main.c:172)
==7309==
==7309== 20 bytes in 1 blocks are definitely lost in loss record 2 of 6
==7309== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7309== by 0x400B76: makeargv (main.c:49)
==7309== by 0x400CD4: parse_file (main.c:120)
==7309== by 0x400DFF: main (main.c:172)
==7309==
==7309== 160 bytes in 1 blocks are definitely lost in loss record 5 of 6
==7309== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7309== by 0x400A6E: makeargv (main.c:32)
==7309== by 0x400CD4: parse_file (main.c:120)
==7309== by 0x400DFF: main (main.c:172)
==7309==
==7309== LEAK SUMMARY:
==7309== definitely lost: 196 bytes in 3 blocks
==7309== indirectly lost: 0 bytes in 0 blocks
==7309== possibly lost: 0 bytes in 0 blocks
==7309== still reachable: 888 bytes in 3 blocks
==7309== suppressed: 0 bytes in 0 blocks
==7309== Reachable blocks (those to which a pointer was found) are not shown.
==7309== To see them, rerun with: --leak-check=full --show-reachable=yes
==7309==
==7309== For counts of detected and suppressed errors, rerun with: -v
==7309== Use --track-origins=yes to see where uninitialised values come from
==7309== ERROR SUMMARY: 7 errors from 6 contexts (suppressed: 2 from 2)
Segmentation fault (core dumped)
makeargv
中的argvp
变量是一个指针数组,但是当您为它分配内存时,您使用的是sizeof(int)
,在64位系统中,该变量只有四个字节,而指针是8个字节
因此,您写入的内容超出了数组的末尾—这就是为什么它报告您在20字节块的偏移量16处写入8字节,因此与块的末尾重叠4字节
在分配
argvp
数组时,使用sizeof(char*)
获取指针的正确大小。注意:该函数内存泄漏严重。你会带着极大的偏见泄露160个字符的分配。是的,我计划修复很多内存泄漏。我看到很多东西可能会被淘汰,但我只是确保所有东西都事先分配好了,因为当我不这样做的时候,它似乎会做一些奇怪的事情。我只是想知道为什么所有的东西都有丰富的记忆,却找不到空间来存放任何东西。
==7309== Memcheck, a memory error detector
==7309== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==7309== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==7309== Command: ./custmake
==7309==
==7309== Invalid write of size 8
==7309== at 0x400C23: makeargv (main.c:62)
==7309== by 0x400CD4: parse_file (main.c:120)
==7309== by 0x400DFF: main (main.c:172)
==7309== Address 0x51f25c0 is 16 bytes inside a block of size 20 alloc'd
==7309== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7309== by 0x400B76: makeargv (main.c:49)
==7309== by 0x400CD4: parse_file (main.c:120)
==7309== by 0x400DFF: main (main.c:172)
==7309==
==7309== Use of uninitialised value of size 8
==7309== at 0x4C2BFC2: __GI_strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7309== by 0x4EA2CEB: puts (ioputs.c:37)
==7309== by 0x400D09: parse_file (main.c:128)
==7309== by 0x400DFF: main (main.c:172)
==7309==
==7309== Invalid read of size 1
==7309== at 0x4C2BFC2: __GI_strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7309== by 0x4EA2CEB: puts (ioputs.c:37)
==7309== by 0x400D09: parse_file (main.c:128)
==7309== by 0x400DFF: main (main.c:172)
==7309== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==7309==
==7309==
==7309== Process terminating with default action of signal 11 (SIGSEGV)
==7309== Access not within mapped region at address 0x0
==7309== at 0x4C2BFC2: __GI_strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7309== by 0x4EA2CEB: puts (ioputs.c:37)
==7309== by 0x400D09: parse_file (main.c:128)
==7309== by 0x400DFF: main (main.c:172)
==7309== If you believe this happened as a result of a stack
==7309== overflow in your program's main thread (unlikely but
==7309== possible), you can try to increase the size of the
==7309== main thread stack using the --main-stacksize= flag.
==7309== The main thread stack size used in this run was 8388608.
==7309==
==7309== HEAP SUMMARY:
==7309== in use at exit: 1,084 bytes in 6 blocks
==7309== total heap usage: 7 allocs, 1 frees, 1,100 bytes allocated
==7309==
==7309== 16 bytes in 1 blocks are definitely lost in loss record 1 of 6
==7309== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7309== by 0x400BCB: makeargv (main.c:59)
==7309== by 0x400CD4: parse_file (main.c:120)
==7309== by 0x400DFF: main (main.c:172)
==7309==
==7309== 20 bytes in 1 blocks are definitely lost in loss record 2 of 6
==7309== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7309== by 0x400B76: makeargv (main.c:49)
==7309== by 0x400CD4: parse_file (main.c:120)
==7309== by 0x400DFF: main (main.c:172)
==7309==
==7309== 160 bytes in 1 blocks are definitely lost in loss record 5 of 6
==7309== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7309== by 0x400A6E: makeargv (main.c:32)
==7309== by 0x400CD4: parse_file (main.c:120)
==7309== by 0x400DFF: main (main.c:172)
==7309==
==7309== LEAK SUMMARY:
==7309== definitely lost: 196 bytes in 3 blocks
==7309== indirectly lost: 0 bytes in 0 blocks
==7309== possibly lost: 0 bytes in 0 blocks
==7309== still reachable: 888 bytes in 3 blocks
==7309== suppressed: 0 bytes in 0 blocks
==7309== Reachable blocks (those to which a pointer was found) are not shown.
==7309== To see them, rerun with: --leak-check=full --show-reachable=yes
==7309==
==7309== For counts of detected and suppressed errors, rerun with: -v
==7309== Use --track-origins=yes to see where uninitialised values come from
==7309== ERROR SUMMARY: 7 errors from 6 contexts (suppressed: 2 from 2)
Segmentation fault (core dumped)