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

C语言凯撒密码操作字符串指针时主调函数buffer值不更新问题

问题原因拆解
  • 首先C语言的函数参数是值传递:你给encrypt函数传的是buffer指针的拷贝,函数内部对buffer指针本身的赋值(buffer = (unsigned char *)temp_buffer;)只会修改这个局部拷贝的指向,完全不会影响main函数里的原buffer变量,所以外部看不到修改。
  • 其次你直接用strcpy会段错误的原因:main函数里的buffer指向的是字符串常量,这类数据存放在进程的只读数据段,没有写入权限,直接往这个地址复制内容会触发内存访问违例。

另外你原有encrypt函数还存在两处隐藏bug:

  • malloc(strlen(buffer)) 少分配了1字节的空间,字符串末尾的'\0'没有地方存,会造成堆溢出。
  • memset(temp_buffer, '\0', sizeof(temp_buffer)) 写法错误:temp_buffer是指针类型,sizeof(temp_buffer)拿到的是指针本身的大小(32位系统是4字节,64位是8字节),不是你申请的内存空间的总长度,初始化不完整。
可行解决方法

以下是三种常用的兼容实现方案:

方案1:函数返回加密后的字符串指针,主函数接收后使用、手动释放

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

unsigned char* encrypt(unsigned char *src) {
    unsigned int i;
    size_t len = strlen(src);
    // 多分配1字节存结尾'\0'
    unsigned char *temp_buffer = (unsigned char *)malloc(len + 1);
    // 按申请的内存总长度初始化
    memset(temp_buffer, '\0', len + 1);

    for(i = 0; i < len; i++) {
        temp_buffer[i] = src[i] + 2;
    }
    temp_buffer[len] = '\0';
    printf("%s\n", temp_buffer); //输出加密后的内容
    
    return temp_buffer;
}

int main() {
    unsigned char *src = "hello world";
    printf("%s\n", src); //hello world

    unsigned char *encrypted = encrypt(src);
    printf("%s\n", encrypted); //输出预期的jgnnm"umpnf
    // 用完释放堆内存,避免内存泄漏
    free(encrypted);

    return 0;
}

方案2:传递二级指针,直接修改原指针的指向

如果不需要保留原字符串,可以用二级指针的方式,函数内部直接修改main函数里的指针指向:

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

int encrypt(unsigned char **buffer) {
    unsigned char *src = *buffer;
    unsigned int i;
    size_t len = strlen(src);
    unsigned char *temp_buffer = (unsigned char *)malloc(len + 1);
    memset(temp_buffer, '\0', len + 1);

    for(i = 0; i < len; i++) {
        temp_buffer[i] = src[i] + 2;
    }
    temp_buffer[len] = '\0';
    printf("%s\n", temp_buffer);
    // 修改原指针的指向,指向新申请的加密内存
    *buffer = temp_buffer;
    
    return 0;
}

int main() {
    unsigned char *buffer = "hello world";
    printf("%s\n", buffer); //hello world

    encrypt(&buffer);
    printf("%s\n", buffer); //输出预期的加密内容
    free(buffer); //记得释放堆内存

    return 0;
}

方案3:主函数提前分配可写缓冲区,传进去直接修改

如果不想手动管理堆内存,也可以在主函数开栈上的可写数组,把数组地址传进去,函数内部直接修改数组内容即可:

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

int encrypt(unsigned char *buffer, size_t buf_len) {
    unsigned int i;
    // 直接在传入的可写缓冲区上修改
    for(i = 0; i < buf_len && buffer[i] != '\0'; i++) {
        buffer[i] = buffer[i] + 2;
    }
    printf("%s\n", buffer);
    return 0;
}

int main() {
    // 开栈上的可写数组,初始化内容为hello world
    unsigned char buffer[32] = "hello world";
    printf("%s\n", buffer); //hello world

    encrypt(buffer, sizeof(buffer));
    printf("%s\n", buffer); //输出预期的加密内容
    // 栈内存会自动回收,不需要手动释放
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 22:45:03