用C实现的简易HTTP解析器运行数轮后停止工作求助
Hey there! Let's break down what's going wrong with your parser and fix it step by step—since you're only two weeks into C, it's totally normal to hit these memory management snags!
The Key Issues in Your Current Code
I spotted three critical problems that are causing your parser to fail after multiple runs:
- Incorrect
memsetusage:sizeof contentreturns the size of the pointer (4 bytes on 32-bit systems, 8 on 64-bit), not thesizebytes you allocated withmalloc. This leaves most of yourcontentbuffer filled with uninitialized garbage data, leading to undefined behavior. - Missing string terminator: C strings require a
'\0'to mark their end. When your loop breaks early onend_token, you don't add this terminator—so any string operations (likeprintforstrlen) will read past the valid content into random memory, often causing crashes. - No
mallocfailure check: Ifmallocruns out of memory (common after multiple runs), it returnsNULL. Trying to write toNULLwill cause an immediate segmentation fault.
Fixed Parser Code
Here's a revised version with all issues addressed, plus comments explaining each change:
#include <stdlib.h> #include <string.h> char *parser(const char *buf, int size, char end_token) { // Guard against invalid input first if (buf == NULL || size <= 0) { return NULL; } // Allocate extra byte for the null terminator char *content = malloc((size_t)size + 1); if (content == NULL) { return NULL; // Return early if memory allocation fails } // Clear the entire allocated buffer (including the extra byte) memset(content, 0, (size_t)size + 1); int i; for (i = 0; i < size; i++) { // Use array notation for readability (equivalent to *(buf+i)) if (buf[i] == end_token) { break; } content[i] = buf[i]; } // Explicitly add null terminator (redundant here due to memset, but safe practice) content[i] = '\0'; return content; }
Critical Usage Note
When you call this parser, you must free the returned buffer to avoid memory leaks. Over multiple runs, leaked memory will build up and eventually crash your program:
// Example usage char *parsed_content = parser(socket_buffer, received_size, '<'); // Stop at first '<' for HTML if (parsed_content != NULL) { printf("Parsed data: %s\n", parsed_content); free(parsed_content); // Don't forget this! }
Bonus Tip
If you want to optimize a bit, you can skip the memset entirely by just setting the null terminator after the loop—this saves a bit of time, but memset makes the code safer if you ever modify the loop logic later.
内容的提问来源于stack exchange,提问作者GabrielChu

