REALLOC()可能的泄漏:当Realloc()在分配内存时失败时,原始指针会丢失
我知道这已经很多次了,但似乎每次都发生了这个问题的发生略有不同。
我有以下C应用程序,该应用程序从称为word_generator()
的函数接收一个字符串,然后对每个传入的字符串进行过滤,并且一旦满足条件,则将当前字符串存储在char数组中,称为<代码> output_char_buffer 。
由于传入数据具有可变长度,因此需要动态调整该过程中涉及的字符阵列。
该应用程序似乎正在起作用,但是静态分析工具正在抱怨以下消息:
warning: V701 realloc() possible leak: when realloc() fails in allocating memory, original pointer 'output_char_buffer' is lost.
Consider assigning realloc() to a temporary pointer.
这是代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *word_generator(int selector)
{
switch(selector)
{
case 0:
return "gpu-log-02_05_2022_12_37_56_784";
break;
case 1:
return "glsl-debug.txt";
break;
case 2:
return "compiler.log";
break;
case 3:
return "shader.pub";
break;
case 4:
return "fluid-sim-variantA.cache";
break;
default:
printf("ERROR: Request out of range!\n");
}
return "";
}
int main() {
char *output_char_buffer;
output_char_buffer = NULL;
// Simulate incoming data.
for (int i = 0; i < 5; i++)
{
printf("Test string[%d]: %s\n", i, word_generator(i));
unsigned long local_buffer_length = strlen(word_generator(i));
unsigned long input_buffer_length = 0;
char *input_char_buffer = (char*)malloc(local_buffer_length + 1);
if (input_char_buffer != NULL)
{
strcpy(input_char_buffer, word_generator(i));
input_buffer_length = strlen(input_char_buffer);
}
else
{
// Clean-up.
free(input_char_buffer);
input_char_buffer = NULL;
printf("ERROR: Failed to allocate char buffer memory!\n");
// Exit with an error state.
return 1;
}
// Verbose debug.
printf("\tCurrent input buffer (value: %s, length: %lu)\n", input_char_buffer, input_buffer_length);
char key[] = "compiler.log";
// Verbose debug.
printf("\tCurrent key (value: %s, length: %lu)\n", key, strlen(key));
if (strcmp(input_char_buffer, key) == 0)
{
printf("\t\t__MATCH__\n");
output_char_buffer = (char*)realloc(output_char_buffer, (local_buffer_length + 1));
if (output_char_buffer != NULL)
{
strcpy(output_char_buffer, input_char_buffer);
}
else
{
// Clean-up.
free(output_char_buffer);
output_char_buffer = NULL;
printf("ERROR: Failed to fetch char buffer memory!\n");
// Exit with an error state.
return 1;
}
}
// Clean-up.
free(input_char_buffer);
input_char_buffer = NULL;
}
// Check the final value of the string container.
printf("Result: %s\n", output_char_buffer);
// Clean-up and finish.
free(output_char_buffer);
output_char_buffer = NULL;
return 0;
}
输出:
Test string[0]: gpu-log-02_05_2022_12_37_56_784
Current input buffer (value: gpu-log-02_05_2022_12_37_56_784, length: 31)
Current key (value: compiler.log, length: 12)
Test string[1]: glsl-debug.txt
Current input buffer (value: glsl-debug.txt, length: 14)
Current key (value: compiler.log, length: 12)
Test string[2]: compiler.log
Current input buffer (value: compiler.log, length: 12)
Current key (value: compiler.log, length: 12)
__MATCH__
Test string[3]: shader.pub
Current input buffer (value: shader.pub, length: 10)
Current key (value: compiler.log, length: 12)
Test string[4]: fluid-sim-variantA.cache
Current input buffer (value: fluid-sim-variantA.cache, length: 24)
Current key (value: compiler.log, length: 12)
Result: compiler.log
该问题标记的行是:
output_char_buffer = (char*)realloc(output_char_buffer, (local_buffer_length + 1));
解决此问题的安全方法是什么?
I know this has been asked many many times, but it seems like the occurrence of this issue is slightly different every time.
I have the following C application, that receives a string from a function called word_generator()
, then every incoming string is filtered and once the condition is met, the current string is stored in a char array called output_char_buffer
.
Since the incoming data has a variable length, the char arrays involved in the process needs to be dynamically resized.
The application seems to be working, but the static analysis tool is complaining with the following message:
warning: V701 realloc() possible leak: when realloc() fails in allocating memory, original pointer 'output_char_buffer' is lost.
Consider assigning realloc() to a temporary pointer.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *word_generator(int selector)
{
switch(selector)
{
case 0:
return "gpu-log-02_05_2022_12_37_56_784";
break;
case 1:
return "glsl-debug.txt";
break;
case 2:
return "compiler.log";
break;
case 3:
return "shader.pub";
break;
case 4:
return "fluid-sim-variantA.cache";
break;
default:
printf("ERROR: Request out of range!\n");
}
return "";
}
int main() {
char *output_char_buffer;
output_char_buffer = NULL;
// Simulate incoming data.
for (int i = 0; i < 5; i++)
{
printf("Test string[%d]: %s\n", i, word_generator(i));
unsigned long local_buffer_length = strlen(word_generator(i));
unsigned long input_buffer_length = 0;
char *input_char_buffer = (char*)malloc(local_buffer_length + 1);
if (input_char_buffer != NULL)
{
strcpy(input_char_buffer, word_generator(i));
input_buffer_length = strlen(input_char_buffer);
}
else
{
// Clean-up.
free(input_char_buffer);
input_char_buffer = NULL;
printf("ERROR: Failed to allocate char buffer memory!\n");
// Exit with an error state.
return 1;
}
// Verbose debug.
printf("\tCurrent input buffer (value: %s, length: %lu)\n", input_char_buffer, input_buffer_length);
char key[] = "compiler.log";
// Verbose debug.
printf("\tCurrent key (value: %s, length: %lu)\n", key, strlen(key));
if (strcmp(input_char_buffer, key) == 0)
{
printf("\t\t__MATCH__\n");
output_char_buffer = (char*)realloc(output_char_buffer, (local_buffer_length + 1));
if (output_char_buffer != NULL)
{
strcpy(output_char_buffer, input_char_buffer);
}
else
{
// Clean-up.
free(output_char_buffer);
output_char_buffer = NULL;
printf("ERROR: Failed to fetch char buffer memory!\n");
// Exit with an error state.
return 1;
}
}
// Clean-up.
free(input_char_buffer);
input_char_buffer = NULL;
}
// Check the final value of the string container.
printf("Result: %s\n", output_char_buffer);
// Clean-up and finish.
free(output_char_buffer);
output_char_buffer = NULL;
return 0;
}
Output:
Test string[0]: gpu-log-02_05_2022_12_37_56_784
Current input buffer (value: gpu-log-02_05_2022_12_37_56_784, length: 31)
Current key (value: compiler.log, length: 12)
Test string[1]: glsl-debug.txt
Current input buffer (value: glsl-debug.txt, length: 14)
Current key (value: compiler.log, length: 12)
Test string[2]: compiler.log
Current input buffer (value: compiler.log, length: 12)
Current key (value: compiler.log, length: 12)
__MATCH__
Test string[3]: shader.pub
Current input buffer (value: shader.pub, length: 10)
Current key (value: compiler.log, length: 12)
Test string[4]: fluid-sim-variantA.cache
Current input buffer (value: fluid-sim-variantA.cache, length: 24)
Current key (value: compiler.log, length: 12)
Result: compiler.log
The line flagged for the issue is this one:
output_char_buffer = (char*)realloc(output_char_buffer, (local_buffer_length + 1));
What would be the safe way to handle this problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
代码中有2个实例
realloc
。在第二个中,原始指针确实被覆盖:您应该将返回值存储到临时变量中,以便在失败的情况下释放原始指针,从而避免内存泄漏。
还要注意,代码中的清理不完整:您应该释放
input_char_buffer
和output_char_buffer
,以防万一在上一次迭代中分配了。这是一个修改版本:
There are 2 instances of
realloc
in the code. In the second one, the original pointer is indeed overwritten:You should instead store the return value into a temporary variable so you can free the original pointer in case of failure, thus avoiding a memory leak.
Also note that the cleanup in your code is incomplete: you should free both the
input_char_buffer
and theoutput_char_buffer
in case it has been allocated during a previous iteration.Here is a modified version: