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

C语言通过新指针构造字符串并赋值给原指针的两个异常问题

问题原因与修复方案

问题1:指针地址无变化的疑问

你打印的是指针变量自身在栈上的存储地址,而非指针指向的堆内存地址:

  • row是main函数中定义的局部指针变量,它的存储位置固定,因此&row的值全程不会变化
  • newRow是for循环内的局部指针变量,每次循环都会在栈的相同位置创建该变量,因此&newRow的值也不会变化
    如果要查看每次malloc申请的堆内存地址,直接打印row和newRow本身的值即可,不需要取地址。

问题2:字符串末尾出现乱码

这是内存分配不足导致的缓冲区溢出问题:
C语言字符串以\0作为结束标志,你每次需要在原字符串前追加1个a,新字符串的总长度为原字符串长度 + 1,加上末尾的\0,总共需要分配的内存大小为strlen(row) + 2,但你代码中仅分配了strlen(row) + 1,少了1字节存储结束符。执行strcpy时会把\0写到分配的内存边界之外,属于未定义行为,会引发字符串乱码、长度计算错误等问题。
另外你代码未引入<string.h>头文件,直接调用strlen、strcpy属于隐式声明,不符合C语言标准要求。

修复后代码

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

int main()
{
  char lineBuf[] = "hello";
  char *row = (char *)malloc(strlen(lineBuf) + 1);
  strcpy(row, lineBuf);

  for (size_t i = 0; i < 40; i++)
  {
    // 修正内存分配大小
    char *newRow = (char *)malloc(strlen(row) + 2);
    // 打印指针指向的堆内存地址
    printf("%ld:  row指向地址: %p, newRow指向地址: %p, len: %ld", i, (void *)row, (void *)newRow, strlen(row));
    newRow[0] = 'a';
    strcpy(newRow + 1, row);
    printf(", string is: %s\n", newRow);
    // 释放旧内存避免泄漏
    free(row);
    row = newRow;
  }
  // 释放最终使用的内存
  free(row);
  return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 14:54:03