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

为何已获内存访问权限仍触发Segmentation fault (core dumped)?字符串反转故障排查

Why Your Reverse String Code Causes a Segmentation Fault

Hey there! Let's walk through exactly what's going wrong with your code and how to fix it. I'll break down the key issues step by step:

1. The Core Problem: String Literals Are Read-Only

The biggest reason you're hitting a segmentation fault is right in your main function:

char *str = "five";

When you assign a string like "five" to a char*, it points to a string literal stored in read-only memory. Any attempt to modify this memory (which your code tries to do in the final while loop with *s = *tmp) will trigger a segmentation fault, since the OS blocks writes to read-only regions.

Fix it by declaring str as a modifiable character array instead:

char str[] = "five";

This copies the string literal into a writable array on the stack, so you can safely modify it.

2. Pointer Out-of-Bounds in malloc Block

Your code has a mistake in how it positions the tmp pointer after malloc:

char *tmp = malloc(length * sizeof(char));
tmp += length;

You allocate length bytes (since _strlen returns the length without the null terminator), but then you move tmp to the position after the last allocated byte. When you write *tmp = *clone, you're writing outside the memory you allocated—this is undefined behavior and can corrupt memory or cause crashes.

Fix it by pointing tmp to the last valid byte of the allocated block, plus allocating space for the null terminator:

char *tmp = malloc((length + 1) * sizeof(char)); // +1 to store the '\0' terminator
char *tmp_original = tmp; // Save the start address to free later
tmp += length - 1; // Point to the last valid byte in the allocated block

3. Missing Null Terminator

After copying the reversed characters into tmp, you need to add a null terminator to mark the end of the string. Add this line after your first while loop:

*(tmp_original + length) = '\0';

This places the \0 at the end of the reversed string in the allocated memory, ensuring functions like printf can read it safely.

4. Memory Leak

You never free the memory you allocated with malloc, which will leave a memory leak. Always pair malloc with free when you're done with the memory. Since you moved the tmp pointer, use the original address you saved (tmp_original) to free it:

free(tmp_original);

Fixed Full Code

Here's the revised version of your code with all these fixes applied:

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

int _strlen(char *s) {
    int len = 0;
    while (*s++) len++;
    return len;
}

void rev_string(char *s) {
    int length = _strlen(s);
    char *clone = s;
    char *tmp = malloc((length + 1) * sizeof(char));
    char *tmp_original = tmp;
    tmp += length - 1;

    while (*clone) {
        *tmp = *clone;
        tmp--;
        clone++;
    }
    *(tmp_original + length) = '\0';

    printf("TMP-->%s,s-->%s\n", tmp_original, s);

    clone = s;
    tmp = tmp_original;
    while (*tmp) {
        *clone = *tmp;
        tmp++;
        clone++;
    }

    free(tmp_original);
}

int main(void) {
    char str[] = "five";
    rev_string(str);
    printf("done\n");
    printf("%s\n", str);
    return (0);
}

Bonus: A More Efficient In-Place Reverse

Since you mentioned you've written more efficient versions, you might want to use an in-place approach that avoids malloc entirely—swap characters from the start and end of the string moving towards the center:

void rev_string_inplace(char *s) {
    int length = _strlen(s);
    char *start = s;
    char *end = s + length - 1;
    char temp;

    while (start < end) {
        temp = *start;
        *start = *end;
        *end = temp;
        start++;
        end--;
    }
}

This uses no extra memory and is faster than allocating a clone.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 11:57:43