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

C语言字符串处理问题:原数组被意外修改,求助排查原因

问题原因分析

1. 数组传参的本质是指针传递

C语言中,栈上数组传递给函数时不会生成副本——函数接收到的是数组首元素的指针。也就是说,stripSpaces里的noSpace指针直接指向usrStr的内存空间,函数内对noSpace的修改(覆盖字符、添加终止符'\0')都会直接作用于原数组,导致后续printf输出的原字符串被改变。

2. const无效的原因

你尝试给usrStr加const但没效果,核心问题在于:

  • 若main中声明const char usrStr[250];,但isPalindrome和stripSpaces的参数是char*(非const指针),把const数组传给非const指针会触发编译警告,且强制编译通过后修改const内存属于未定义行为,根本没解决原问题;
  • 你需要的是保护原数组不被修改,而非简单加const修饰。

解决办法

有两种可行方案,可根据需求选择:

方案一:动态分配新内存存储去空格后的字符串(推荐)

在stripSpaces中为去空格后的字符串分配堆内存,不修改原数组,用完后释放内存避免泄漏。

修改后的完整代码:

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

bool isPalindrome(const char string[]);
char* stripSpaces(const char *noSpace);

int main(void)
{
    char usrStr[250];

    printf("Please enter a string and I will check if it is a palindrome...");
    scanf("%250[^\n]", usrStr);
    
    printf("\n");
    isPalindrome(usrStr) ? printf("\"%s\" is a palindrome", usrStr) : printf("\"%s\" is not a palindrome", usrStr);

    printf("\n");

    return 0;
}

bool isPalindrome(const char* string)
{
    char* newStr = stripSpaces(string);
    if (newStr == NULL) {
        return false;
    }
    
    int middle = strlen(newStr) / 2;
    int len = strlen(newStr);
    bool isPalin = true;

    for(int x = 0; x < middle; x++) {
        if(newStr[x] != newStr[len - x - 1]) {
            isPalin = false;
            break;
        }
    }
    
    free(newStr); // 释放动态分配的内存
    return isPalin;
}

char* stripSpaces(const char *noSpace)
{
    int length = strlen(noSpace);
    int count = 0;

    // 先统计非空格字符数量,按需分配内存
    for(int idx = 0; idx < length; idx++) {
        if(noSpace[idx] != ' ') {
            count++;
        }
    }

    // 分配内存(+1用于存储字符串终止符'\0')
    char *newStr = (char*)malloc(count + 1);
    if(newStr == NULL) {
        perror("Failed to allocate memory");
        return NULL;
    }

    count = 0;
    for(int idx = 0; idx < length; idx++) {
        if(noSpace[idx] != ' ') {
            newStr[count] = noSpace[idx];
            count++;
        }
    }
    newStr[count] = '\0';

    return newStr;
}

方案二:使用临时数组存储原字符串副本

如果不想用动态内存,可在isPalindrome中创建临时数组,复制原字符串后对副本执行去空格操作,原数组不受影响。

修改后的核心代码:

bool isPalindrome(const char* string)
{
    char tempStr[250]; // 临时数组长度与原数组一致
    strcpy(tempStr, string); // 复制原字符串到临时数组
    
    char* newStr = stripSpaces(tempStr); // 对临时数组去空格
    
    int middle = strlen(newStr) / 2;
    int len = strlen(newStr);

    for(int x = 0; x < middle; x++) {
        if(newStr[x] != newStr[len - x - 1]) {
            return false;
        }
    }
    
    return true;
}

// stripSpaces函数可保持原实现,建议参数改为char*明确操作临时数组
char* stripSpaces(char *noSpace)
{
    int length = strlen(noSpace);
    int count = 0;
    for(int idx = 0; idx < length; idx++)
    {
        if(noSpace[idx] != ' ')
        {
            noSpace[count] = noSpace[idx];
            count++;
        }
    }
    noSpace[count] = '\0';

    return noSpace;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 14:00:27