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

C语言传递字符串指针到函数后打印附带内存地址的问题排查

问题根因

这个问题和栈内存机制、指针损坏没有任何关系,属于标准输出缓冲导致的输出拼接错觉:你看到的字符串末尾的144根本不是内存里的脏数据或者地址值,而是后续代码打印的sum变量计算结果。
具体执行逻辑如下:

  • 你在main中定义的char* n = "function pointers"完全合法,字符串字面量自带\0结束符,将其作为实参传递给topic函数的过程中,指针值没有被破坏,指向的内存内容始终正确。
  • 问题出在topic函数内的打印语句:
    printf("Hello, %s, today's topic id is %s",p,arg);
    
    这行代码的格式字符串末尾没有添加换行符\n。C语言的标准输出stdout默认是行缓冲模式:缓冲区中存储的打印内容,只有遇到换行符、缓冲区写满、主动调用fflush(stdout)、程序正常退出时,才会真正显示到终端上。这行语句执行完后,所有待打印的内容都留在输出缓冲区中,没有立刻显示。
  • topic函数执行完返回main后,代码继续运行:通过函数指针调用F(97,47),计算得到sum = 97 + 47 = 144,紧接着执行printf("%i",sum);,这行要打印的144会直接追加到现有输出缓冲区的尾部,正好接在之前缓冲区存储的function pointers内容后面。
  • 等main函数执行完毕、程序准备退出时,C运行时会自动刷新所有输出缓冲区,此时拼接后的整段内容才会一次性显示到屏幕上,让你误以为是打印arg指针指向的字符串时带出了额外内容。
修复方式

只需要给topic函数内的printf格式串末尾加上换行符,让缓冲区内容在该语句执行完就立刻刷新即可:

printf("Hello, %s, today's topic id is %s\n",p,arg);

修改后你会看到两段输出正常分行显示,不会再出现字符串末尾拼接144的现象。

其他潜在问题提醒
  • 代码中scanf("%s",p)存在堆缓冲区溢出风险:你给p只申请了20字节的堆内存,%s格式符默认会一直读取输入直到遇到空白符,如果用户输入超过19个字符就会越界写入堆内存,触发未定义行为,建议改成scanf("%19s",p)限制最大读取长度。
  • isalnum类字符检测函数要求传入参数必须是能转换为unsigned char的值或者EOF,如果当前编译环境下char为有符号类型,遇到值为负的字符时会触发未定义行为,循环判断逻辑建议修改为while (isalnum((unsigned char)*p) == 0);,原代码里的双重取反!!属于无意义的冗余写法。
  • C标准明确规定sizeof(char)的值固定为1,malloc(20*sizeof(char))可以直接简写为malloc(20),不影响功能但写法更简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 22:18:22