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

自定义随机字符串生成器中memcpy复制目标字符串出现垃圾字符问题求助

问题分析与修复方案

你的代码出现的两个问题,根源集中在字符串存储的数组声明错误、字符串复制未处理终止符以及变量作用域误用这几个点上,咱们一步步拆解解决:

核心问题拆解

1. 错误的二维数组声明

你用了char data[num_data][string_length];,但string_length在声明时是未初始化的变量,而且它的值是后续循环里动态变化的——C语言的变长数组(VLA)要求声明时大小必须是确定的,这直接导致data的每个元素长度完全不可控,要么是随机垃圾值,要么无法适配后续不同长度的字符串,这是残留内容和垃圾字符出现的核心原因。

2. 字符串复制未处理终止符

memcpy(data[i], str, sizeof(str))只复制了str里的字符,没把字符串的终止符'\0'复制进去,而且data[i]的长度和str不匹配时,打印会越界读取内存里的垃圾内容。

3. 重复检查时的变量作用域错误

当检测到重复字符串时,你在for循环内部重新声明了char str[string_length];,这个str是内层局部变量,和外面的str完全不是同一个——也就是说,你重新生成的字符串根本没替换掉原来的重复字符串,后续还是会把重复内容存进去。

4. 未初始化随机数种子

rand()在调用前没有用srand()初始化种子,每次运行程序生成的随机序列都是一样的,这虽然不是当前的直接问题,但也是随机生成器的必要优化点。

修复后的完整代码

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

// Random string generator
void rand_str(char *dest, size_t length) {
    char charset[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    int charset_length = 62;
    while (length-- > 0) {
        size_t index = rand() % charset_length;
        *dest++ = charset[index];
    }
    *dest = '\0'; // 确保终止符被写入
}

int main () {
    int num_data = 5;
    int max_string_length = 10;
    // 用指针数组存储每个动态分配的字符串,适配不同长度
    char *data[num_data];
    int i = 0;

    // 初始化随机数种子,让每次运行的随机序列不同
    srand((unsigned int)time(NULL));

    while (i < num_data) {
        // 生成3到max_string_length+2之间的长度(原逻辑:3 + 0~9 → 3~12)
        int string_length = 3 + (rand() % max_string_length);
        // 动态分配内存,多留1字节存终止符
        char *str = malloc(string_length + 1);
        if (!str) {
            perror("malloc failed");
            exit(EXIT_FAILURE);
        }
        rand_str(str, string_length);

        // 循环检查并生成,直到得到不重复的字符串
        int is_duplicate = 0;
        do {
            is_duplicate = 0;
            for (int j = 0; j < i; j++) {
                if (!strcmp(data[j], str)) {
                    is_duplicate = 1;
                    free(str); // 释放重复的字符串内存
                    string_length = 3 + (rand() % max_string_length);
                    str = malloc(string_length + 1);
                    if (!str) {
                        perror("malloc failed");
                        exit(EXIT_FAILURE);
                    }
                    rand_str(str, string_length);
                    break;
                }
            }
        } while (is_duplicate);

        // 把生成的字符串存入data数组
        data[i] = str;
        printf("生成的字符串:%s\n", str);
        printf("存储的字符串:%s\n\n", data[i]);
        i++;
    }

    // 释放动态分配的内存,避免内存泄漏
    for (int j = 0; j < num_data; j++) {
        free(data[j]);
    }

    return 0;
}

关键修复点说明

  • 改用指针数组+动态内存分配:每个字符串根据实际长度动态分配内存,完美适配不同长度的字符串,彻底解决残留内容问题。
  • 确保字符串终止符正确写入:rand_str里明确写入'\0',动态分配时多留一个字节,保证终止符有存储空间。
  • 修复重复检查逻辑:用do-while循环重复生成,直到得到不重复的字符串,同时修正了变量作用域问题,确保更新的是同一个字符串变量。
  • 初始化随机数种子:让每次运行生成的随机序列都不一样,符合随机生成器的预期。
  • 添加内存释放逻辑:避免内存泄漏,养成良好的C语言编程习惯。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 12:54:09