动态内存分配引发Shadow Bytes问题:LeetCode日志限流代码报错求助
Hey there! Let's dig into why you're hitting those shadow bytes and heap buffer overflow warnings on LeetCode—your local setup might not be catching the issue because of different memory sanitizer settings, but LeetCode's test environment is stricter.
The Core Problem: Wrong calloc Usage
The biggest bug here is in your loggerCreate function. Let's look at this problematic line:
logger->log_array = calloc(0, LOGLIST * sizeof *logger->log_array);
calloc takes two arguments in order: number of elements first, then size per element. You’ve flipped them and passed 0 as the element count, which means you’re allocating 0 bytes of memory for your log array.
When you later try to access obj->log_array[hashval] (where hashval ranges from 0 to 99), you’re writing to memory that hasn’t been allocated to your program. This is a classic heap buffer overflow, which triggers the shadow bytes warning—those are the memory sanitizer’s way of flagging out-of-bounds memory access.
Fixing the Memory Allocation
Change the calloc line to correctly request LOGLIST elements, each of size int:
logger->log_array = calloc(LOGLIST, sizeof *logger->log_array);
calloc automatically initializes all elements to 0, which aligns perfectly with your logic of checking if *ht == 0 (meaning the message hasn’t been logged before).
Other Minor Notes (Optional but Good to Know)
- Your hash function (summing ASCII values) is very simple and could lead to frequent collisions (e.g., "ab" and "ba" would have the same hash). For fewer collisions, you could use a more robust hash (like multiplying by a prime number as you iterate through the string), but this isn’t causing the overflow issue.
- In
loggerShouldPrintMessage, the condition*ht + 10 <= timestamp || *ht == 0carries a small risk of integer overflow if*htis an extremely large timestamp, but this isn’t the immediate problem with your current code.
Corrected loggerCreate Function
Logger* loggerCreate() { Logger * logger = malloc(sizeof *logger); // Allocate LOGLIST ints, initialized to 0 logger->log_array = calloc(LOGLIST, sizeof *logger->log_array); return logger; }
Why Local Debugging Didn't Catch It?
Local GCC/GDB doesn’t enable memory sanitization by default. If you compile with gcc -fsanitize=address your_code.c and run the program, you’ll see the same heap overflow warning that LeetCode shows—it’s a fantastic tool for catching these memory bugs early!
内容的提问来源于stack exchange,提问作者plexus-creator

