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

C语言指针数组malloc与strcpy代码内存安全及分配问题咨询

问题1:第一段代码是否存在内存泄漏?valgrind -s无输出是否代表无内存问题
  • 这段代码不存在内存泄漏:你对tokens[0]申请的动态内存已经通过free(tokens[0])完成了释放,剩余两个指针tokens[1]、tokens[2]没有申请过堆内存,不存在未释放的动态内存。
  • valgrind -s运行无输出不能完全代表代码没有内存问题:

    首先当前代码本身存在非泄漏类的隐患:你引入的<malloc.h>不是C标准库的标准头文件,标准动态内存分配的头文件是<stdlib.h>,部分编译器可能不支持<malloc.h>导致编译失败。其次全局数组tokens的tokens[1]、tokens[2]未初始化,如果后续代码误访问会触发野指针问题,只是当前代码没有用到这两个指针,valgrind不会触发报错。
    除此之外valgrind只能检测运行时实际执行到的路径的内存问题,如果代码存在未执行路径的内存错误、非内存访问类的逻辑错误,valgrind也不会给出提示。

问题2:如何一次性给tokens数组的三个指针分配内存

你原来的写法错误原因是:把多个字符串所需的长度求和后只赋值给了tokens[0],tokens[1]、tokens[2]仍然没有指向有效的内存地址,所以无法正常运行。

正确的实现逻辑是:先计算三个字符串所需的总内存大小,一次性申请一块连续的堆内存,再手动给三个指针分别指向这块内存中对应的偏移位置即可,示例代码如下:

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

char *tokens[3];

int main()
{
    // 预定义要存储的三个字符串
    const char *str1 = "<html>";
    const char *str2 = "<title>";
    const char *str3 = "<body>";
    // 计算总内存需求:每个字符串长度+1(存储结束符'\0')的总和
    size_t total_size = (strlen(str1) + 1) + (strlen(str2) + 1) + (strlen(str3) + 1);
    // 一次性申请总内存,首地址赋值给第一个指针
    tokens[0] = malloc(total_size);
    if (tokens[0] == NULL) {
        perror("内存申请失败");
        return 1;
    }
    // 给剩余两个指针分配对应偏移位置
    tokens[1] = tokens[0] + strlen(str1) + 1;
    tokens[2] = tokens[1] + strlen(str2) + 1;
    // 拷贝字符串到对应位置
    strcpy(tokens[0], str1);
    strcpy(tokens[1], str2);
    strcpy(tokens[2], str3);

    // 测试输出
    printf("%s\n%s\n%s\n", tokens[0], tokens[1], tokens[2]);

    // 释放时只需释放首地址即可,不需要逐个释放三个指针
    free(tokens[0]);
    return 0;
}

这种分配方式的优势是减少内存碎片,同时避免多次free出现漏释放的问题,注意如果后续需要修改某个指针对应的字符串长度,不能超过预分配的对应位置的内存大小,否则会出现内存越界。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 17:06:08