You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言自定义replace函数的动态内存管理问题排查

Troubleshooting Your Custom C Replace Function

Let's break down the issues in your code that are causing the garbled output and runtime anomalies—most of them tie back to dynamic memory management and string termination, which are easy pitfalls in C:

1. Uninitialized new_text Breaks strcat

You start with char *new_text = malloc(new_text_size); where new_text_size is 0. While malloc(0) is implementation-defined (it might return NULL or a dummy pointer), the bigger problem is that new_text isn't initialized as an empty, null-terminated string. When you first call strcat(new_text, with), strcat looks for a \0 to start appending, and since your buffer is uninitialized, it'll read random memory until it finds one—this is exactly what's causing the weird <0� garbage at the start of your output.

Fix: Initialize new_text as an empty string from the get-go:

char *new_text = malloc(1); // Allocate space for the null terminator
new_text[0] = '\0';
int new_text_size = 0; // Keep track of the actual character count (excluding null terminator)

2. Missing Null Terminator in new_text

Your loop builds new_text character by character or appends replacement strings, but you never add a final \0 to terminate the string. When you later call strcpy(*text, new_text), strcpy will keep reading past the end of your buffer until it hits a random null byte, leading to unexpected behavior.

Fix: After the loop finishes, resize new_text to make space for the terminator and add it:

// After the do-while loop
new_text = realloc(new_text, new_text_size + 1);
new_text[new_text_size] = '\0';

3. Insufficient Memory for the Final *text

When you assign *text = malloc(new_text_size);, you're not accounting for the null terminator. This means strcpy will write the terminator outside the allocated buffer, causing undefined behavior (like corrupting other memory).

Fix: Allocate an extra byte for the null terminator:

*text = malloc(new_text_size + 1);
strcpy(*text, new_text);

4. Memory Leak from new_text

You never free the new_text buffer after copying its contents to *text. This will leave allocated memory hanging around, which is a bad practice in long-running programs.

Fix: Add free(new_text); right after copying to *text.

5. Minor Loop Adjustment (Avoiding Off-by-One)

Your do-while loop works mostly fine, but let's double-check: when you process the last character of the original string, p increments to \0, and the loop exits. That's correct, but to keep things safe, I added a null terminator every time we append a single character to new_text—this ensures the buffer is always valid for any intermediate operations.

Corrected Full Code

Here's the fixed version with all these changes applied:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void replace_content(char *rep, char *with, char **text) {
    int len_rep = strlen(rep);
    int len_with = strlen(with);
    char *p = *text;
    int new_text_size = 0;
    // Initialize new_text as an empty null-terminated string
    char *new_text = malloc(1);
    new_text[0] = '\0';

    do {
        if (!strncmp(p, rep, len_rep)) {
            new_text_size += len_with;
            new_text = realloc(new_text, new_text_size + 1); // +1 for null terminator
            strcat(new_text, with);
            p += len_rep;
        } else {
            new_text_size++;
            new_text = realloc(new_text, new_text_size + 1); // +1 for null terminator
            new_text[new_text_size - 1] = *p;
            new_text[new_text_size] = '\0'; // Ensure buffer stays terminated
            p++;
        }
    } while (*p != '\0');

    // Allocate proper space for the final text (including null terminator)
    *text = malloc(new_text_size + 1);
    strcpy(*text, new_text);
    // Clean up the temporary buffer
    free(new_text);
}

int main() {
    printf("Testing a replace function:\n");
    char *text = "<serviceName>\n"
                 " <label1>a</label1>\n"
                 " <label2>b</label2>\n"
                 " <label3>c</label3>\n"
                 "</serviceName>\n";
    printf("Before replace:\n%s", text);
    replace_content("serviceName>", "serviceNameResponse>", &text);
    printf("After replace:\n%s", text);
    // Don't forget to free the final text too!
    free(text);
    return 0;
}

Additional Note

I also added free(text); in main() since you're replacing the original pointer with a dynamically allocated one—this prevents another memory leak.

When you run this corrected code, you'll get the expected output without any garbage characters or anomalies.

内容的提问来源于stack exchange,提问作者ArthurTheLearner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:24:14