c - 为什么我会在 C 中得到堆缓冲区溢出?
问题描述
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
if (argc == 1)
exit(EXIT_FAILURE);
int count = 2;
int i, j;
for (i = 1; i < argc; i++)
{
for (j = 0; j < strlen(argv[i]); j++)
count++;
}
printf("%d\n", count);
char* original = malloc(sizeof(char) * count);
printf("%p\n", original);
char* copy = malloc(sizeof(char) * count);
printf("%p\n", copy);
memset(original, 0, strlen(original));
memset(copy, 0, strlen(copy));
strcpy(original, argv[1]);
for (i = 2; i < argc; i++)
{
strcat(original, argv[i]);
}
int coun = 0;
for (i = 0; i < strlen(original); i++)
{
if (original[i] == '(' || original[i] == '{' || original[i] == '[' ||
original[i] == ')' || original[i] == '}' || original[i] == ']')
{
copy[coun] = original[i];
coun++;
}
}
printf("%s\n", original);
printf("%s\n", copy);
free(original);
free(copy);
exit(EXIT_SUCCESS);
}
我使用gcc -Wall -Werror -fsanitize=address balance.c -o balance来制作文件和./balance '(('来测试
我收到了这条消息
问题是什么?
这是获取 argv 内容并仅获取字符串括号的代码。
我得到它可能是错误检查,-fsanitize=address
但我在我的代码上找不到任何错误,所以有人可以检查一下吗?
解决方案
你的问题在这里:
memset(original,0,strlen(original));
memset(copy,0,strlen(copy));
original
和都copy
指向malloc
未初始化的内存。该strlen
函数读取其参数指向的字节,直到找到一个值为 0 的字节。这意味着 1)您正在读取未初始化的内存,以及 2)因为内容不确定,该函数可以读取超过分配内存的末尾。这两个动作都会触发未定义的行为。
您知道两个内存位置都指向count
字节,因此将其传递给memset
:
memset(original,0,count);
memset(copy,0,count);
更好的是,使用calloc
而不是malloc
返回已初始化为 0 的内存:
char* original = calloc(sizeof(char), count);
char* copy = calloc(sizeof(char), count);