for循环中变量j循环一次后被重置为0,求原因及代码建议
问题分析与修复方案
核心问题根源
你遇到的j被意外重置为0的问题,本质是内存越界导致的未定义行为:
- 代码中
char word[] = "";定义了一个长度仅为1的字符数组,里面只存储了字符串终止符\0。 - 当你调用
strcat(word, "p")时,函数会尝试把"p"追加到word末尾,但word没有多余空间,于是会越界写入相邻的内存区域。而变量j恰好存储在这片越界区域,第一次strcat就覆盖了j的值,导致循环条件i < j直接不成立,循环提前终止。
修复后的代码
方式1:动态内存分配+高效赋值(推荐)
这种方式避免了strcat的性能损耗,同时严格管理内存:
#include <cs50.h> #include <stdio.h> #include <string.h> #include <stdlib.h> int main(void) { string prompt = get_string("Give me a word: "); int j = strlen(prompt); // 分配足够内存:j个'p' + 字符串终止符 char *word = malloc(j + 1); // 检查内存分配是否成功 if (word == NULL) { printf("内存分配失败\n"); return 1; } // 逐个写入'p' for (int i = 0; i < j; i++) { word[i] = 'p'; } // 添加字符串终止符,确保printf能正确识别为字符串 word[j] = '\0'; printf("%s\n", word); // 释放动态分配的内存,避免内存泄漏 free(word); return 0; }
方式2:动态内存分配+strcat(兼容你的原始逻辑)
如果想保留strcat的使用逻辑,需要先初始化word为空字符串:
#include <cs50.h> #include <stdio.h> #include <string.h> #include <stdlib.h> int main(void) { string prompt = get_string("Give me a word: "); int j = strlen(prompt); char *word = malloc(j + 1); if (word == NULL) { printf("内存分配失败\n"); return 1; } // 初始化word为空字符串,否则strcat会读取未初始化的内存 word[0] = '\0'; for (int i = 0; i < j; i++) { strcat(word, "p"); } printf("%s\n", word); free(word); return 0; }
额外编程建议
- 禁止内存越界操作:
strcat、strcpy等字符串操作函数不会自动检查目标数组的空间,必须确保目标有足够的存储容量。 - 动态内存管理:使用
malloc分配内存后,一定要用free释放,避免内存泄漏;同时必须检查malloc的返回值,处理分配失败的情况。 - 性能优化:对于重复字符的生成,直接逐个赋值比
strcat高效——strcat每次都要遍历字符串找末尾的\0,循环次数越多,性能损耗越明显。 - CS50注意事项:CS50的
string类型本质是char*,可以直接当作字符指针使用,但同样需要遵守C语言的内存规则。
内容的提问来源于stack exchange,提问作者Boriscodes
相关产品推荐
相关产品推荐

