为什么访问以 null 结尾的字符串会给出 'garbage or undefined'?
Why is accessing a null-terminated string giving 'garbage or undefined'?
我在 C 中有一个简单的 brainfuck 解释器,它在 scan-build
中产生以下警告:
$ scan-build gcc -Wall -g -std=c99 main.c
scan-build: Using '/usr/bin/clang' for static analysis
main.c:14:11: warning: Assigned value is garbage or undefined
c = *(program + instruction_index);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
scan-build: 1 bug found.
这是我的程序中表现出这种行为的最小版本:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <alloca.h>
void eval_program(char *program) {
int program_len = strlen(program);
int data_index = 0, instruction_index = 0;
char c;
while (instruction_index < program_len) {
c = *(program + instruction_index);
switch (c) {
case '>':
data_index++;
instruction_index++;
break;
default:
instruction_index++;
break;
}
}
}
char *read_string(int file_descriptor) {
char *s = NULL;
int total_bytes_read = 0;
int BUFFER_SIZE = sizeof(char) * 1024;
char *temp_buffer = alloca(BUFFER_SIZE);
int bytes_read;
// Not bothering checking the return code from read or realloc for
// errors, because it doesn't affect scan-build's output.
while ((bytes_read = read(file_descriptor, temp_buffer, BUFFER_SIZE))) {
s = realloc(s, total_bytes_read + bytes_read);
memcpy(s + total_bytes_read, temp_buffer, bytes_read);
total_bytes_read += bytes_read;
}
s = realloc(s, total_bytes_read + 1);
s[total_bytes_read] = '[=12=]';
return s;
}
int main() {
char *program = read_string(0); // read from stdin
eval_program(program);
free(program);
return 0;
}
此程序在使用 GCC 和 -Wall -Wextra
编译时不会生成任何警告,那么为什么访问字符串垃圾或未定义?该程序在我的测试中运行良好。
这是一个没有错误检查的最小示例 malloc
或 read
,但是 the warning still occurs if I use error checking。如果我将 realloc
替换为 malloc
.
,也会出现警告
您可以将 read_string() 函数简化为:
char *read_string(int file_descriptor) {
char *s = NULL;
s = malloc(1);
//memset(s,0,1);
s[0] = 0;
return s;
}
如果您在 memset() 调用中发表评论,警告就会消失。因此,我得出结论,在这种情况下,静态分析器是错误的。
代码没有问题。
这是 LLVM 的 clang-analyzer 中的误报错误,请参阅 bug 22289。
我在 C 中有一个简单的 brainfuck 解释器,它在 scan-build
中产生以下警告:
$ scan-build gcc -Wall -g -std=c99 main.c
scan-build: Using '/usr/bin/clang' for static analysis
main.c:14:11: warning: Assigned value is garbage or undefined
c = *(program + instruction_index);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
scan-build: 1 bug found.
这是我的程序中表现出这种行为的最小版本:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <alloca.h>
void eval_program(char *program) {
int program_len = strlen(program);
int data_index = 0, instruction_index = 0;
char c;
while (instruction_index < program_len) {
c = *(program + instruction_index);
switch (c) {
case '>':
data_index++;
instruction_index++;
break;
default:
instruction_index++;
break;
}
}
}
char *read_string(int file_descriptor) {
char *s = NULL;
int total_bytes_read = 0;
int BUFFER_SIZE = sizeof(char) * 1024;
char *temp_buffer = alloca(BUFFER_SIZE);
int bytes_read;
// Not bothering checking the return code from read or realloc for
// errors, because it doesn't affect scan-build's output.
while ((bytes_read = read(file_descriptor, temp_buffer, BUFFER_SIZE))) {
s = realloc(s, total_bytes_read + bytes_read);
memcpy(s + total_bytes_read, temp_buffer, bytes_read);
total_bytes_read += bytes_read;
}
s = realloc(s, total_bytes_read + 1);
s[total_bytes_read] = '[=12=]';
return s;
}
int main() {
char *program = read_string(0); // read from stdin
eval_program(program);
free(program);
return 0;
}
此程序在使用 GCC 和 -Wall -Wextra
编译时不会生成任何警告,那么为什么访问字符串垃圾或未定义?该程序在我的测试中运行良好。
这是一个没有错误检查的最小示例 malloc
或 read
,但是 the warning still occurs if I use error checking。如果我将 realloc
替换为 malloc
.
您可以将 read_string() 函数简化为:
char *read_string(int file_descriptor) {
char *s = NULL;
s = malloc(1);
//memset(s,0,1);
s[0] = 0;
return s;
}
如果您在 memset() 调用中发表评论,警告就会消失。因此,我得出结论,在这种情况下,静态分析器是错误的。
代码没有问题。
这是 LLVM 的 clang-analyzer 中的误报错误,请参阅 bug 22289。