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

动态数组分配问题:valgrind报条件跳转依赖未初始化值

问题分析与修复

你的问题核心是动态分配的字符串没有添加字符串终止符'\0',同时初始分配的内存未初始化,导致strlen读取到未定义的内存区域,触发valgrind的警告。

具体问题点

  • strlen的工作逻辑是从起始地址开始遍历,直到遇到'\0'才停止计数。你的代码仅将输入字符存入数组,但未在末尾添加这个终止符。
  • malloc分配的内存是未初始化的(内存中是随机脏数据),如果输入字符数小于初始分配的10个,msg数组后续的内存是未定义状态,strlen会持续读取这些脏数据,直到碰巧遇到'\0',这直接导致了valgrind的"Conditional jump or move depends on uninitialised value(s)"错误。

修复步骤

  1. 添加字符串终止符:输入循环结束后,在msg[idx]位置写入'\0',确保strlen能正确识别字符串边界。
  2. 调整内存分配空间:初始分配和后续扩容时,多预留1个字节的空间给'\0',避免数组越界。
  3. 可选:初始化内存:可以用calloc替代malloc(自动将内存初始化为0),或用memset手动初始化,即使输入长度不足,后续内存也会是'\0',进一步提升安全性。

修正后的代码

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

int main() {
    char* msg = NULL;
    int c;

    // 初始分配10个字符空间 + 1个字节存'\0'
    size_t size = 10;
    msg = malloc(sizeof(char) * (size + 1));
    if (msg == NULL) { // 必须检查内存分配是否成功
        perror("malloc failed");
        exit(EXIT_FAILURE);
    }

    int idx = 0;
    char* temp = NULL;
    
    while (1) {
        c = getchar();
        if (c == EOF || c == '\n') {
            break;
        } else if (!isalpha(c)) {
            free(msg);
            exit(100);
        }

        // 检查当前索引是否耗尽可用空间(预留1位给'\0')
        if (size <= idx) {
            size *= 2; // 扩容为原大小的2倍
            temp = realloc(msg, sizeof(char) * (size + 1));
            if (temp == NULL) { // 检查扩容是否成功
                free(msg);
                perror("realloc failed");
                exit(EXIT_FAILURE);
            }
            msg = temp;
        }
        msg[idx++] = (char)c;
    }

    // 写入字符串终止符,确保strlen正常工作
    msg[idx] = '\0';
    printf("%ld\n", strlen(msg));

    free(msg); // 释放内存,避免泄漏
    return 0;
}

额外注意事项

  • 每次调用malloc和realloc后,必须检查返回值是否为NULL,防止内存分配失败导致程序崩溃。
  • 最后务必调用free(msg)释放动态分配的内存,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 14:01:38