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
相关产品推荐
相关产品推荐

