#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *delete_comments(char *input) {
unsigned int i = 0;
unsigned int a = 0;
char* dest = malloc( (strlen(input) + 1) * sizeof(char) );
while (i < strlen(input)) {
if(input[i] == '/' && input[i + 1] == '/') {
while (input[i - 1] != '\n') {
}
}
else if (input[i] == '/' && input[i+1] == '*') {
while (input[i-1] != '*' || input[i] != '/') {
i++;
}
}
dest[a] = input[i];
i++;
a++;
}
free(input);
return dest;
}
构建日志:
make -C test valgrind
make[1]: Entering directory '/home/agent/test'
sed -e 's/int[ \t]\{1,\}main[ \t]*[(]/int _no_main(/g;s/void[ \t]\{1,\}main[ \t]*[(]/void _no_main(/g;s/^main[ \t]*[(]/_no_main(/g' ../src/source.c >../src/source.c.nomain.c
gcc -pthread -g -Wall -Wvla -std=c99 -o test test_source.c tmc-check.c checkhelp.c ../src/source.c.nomain.c -lcheck_pic -pthread -lrt -lm -lsubunit
valgrind -q --log-file=valgrind.log --track-origins=yes --leak-check=yes ./test
Running suite(s): Test-08_cleaner
0%: Checks: 1, Failures: 0, Errors: 1
test_source.c:67:E:test_delete_comments:test_delete_comments:0: (after this point) Received signal 11 (Segmentation fault)
make[1]: Leaving directory '/home/agent/test'
Valgrind output:
==44== Invalid read of size 1
==44== at 0x402FB9: delete_comments (source.c.nomain.c:19)
==44== by 0x401E3D: test_delete_comments (test_source.c:74)
==44== by 0x406DE2: srunner_run (in /home/agent/test/test)
==44== by 0x402492: tmc_run_tests (tmc-check.c:134)
==44== by 0x402127: main (test_source.c:206)
==44== Address 0x105b3cc4f is not stack'd, malloc'd or (recently) free'd
==44==
==44==
==44== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==44== Access not within mapped region at address 0x105B3CC4F
==44== at 0x402FB9: delete_comments (source.c.nomain.c:19)
==44== by 0x401E3D: test_delete_comments (test_source.c:74)
==44== by 0x406DE2: srunner_run (in /home/agent/test/test)
==44== by 0x402492: tmc_run_tests (tmc-check.c:134)
==44== by 0x402127: main (test_source.c:206)
==44== If you believe this happened as a result of a stack
==44== overflow in your program's main thread (unlikely but
==44== possible), you can try to increase the size of the
==44== main thread stack using the --main-stacksize= flag.
==44== The main thread stack size used in this run was 2048000
所以这里是代码和 valgrind 报告。我究竟做错了什么?这是用 C 编写的注释删除器代码。我试图查看有关无效读取大小和段错误的前线程,但我并没有真正解决我的问题。我知道如果删除任何评论,我会分配太多内存,但我认为这不会引起问题吗?
编辑:哦,如果您需要用于测试的主要功能,我也可以附加它。
段错误发生在这里:
while (input[i - 1] != '\n') ...
你的计数器i
是一个无符号整数。一开始你有i == 0
并且i - 1
是一个非常大的数字,可能是 2³² − 1。这可能会导致段错误。
请注意,Valgrind 说地址不是“stack'd, malloc'd”。通常,如果你打破了数组的边界,它会说有问题的地址是“超出 malloc 内存的一个字节”或类似的东西。
使用无符号整数作为计数器是一个不错的选择,但是当你倒退时要小心。在您的情况下,您根本不需要向后看:您应该向前推进//
,然后根据需要继续前进。
顺便说strlen()
一句:在 C 中测试循环条件不是一个好主意,因为遍历strlen
整个字符串并查找空终止符。一个聪明的编译器可能会优化它,但最好计算一次字符串长度,或者更好的是,测试是否`input[i] != '\0'。
在跳过具有否定条件的字符时,终止 null 也是您需要考虑的事情。例如,检查当前字符是否不是换行符是不够的。您还必须确保它不是空终止符:
while (input[i] && input[i] != '\n') i++;
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句