使用scanf读取字符串时触发Access violation reading location异常求助
指针存储字符串到二维数组时触发内存访问异常的问题解析
我尝试通过指针将用户输入的字符串存储到二维数组中,但在使用这些字符串时触发了Access violation reading location异常。我首先声明了
char***类型变量来存储二维数组的指针,随后通过循环初始化每个元素。相关代码如下:
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h> #define WORDLEN 80 #define DEFLEN 200 #define KEYVALUE 2 char*** MallocDic(int dictionarySize); char** MallocDicElement(char* word, char* definition); void PrintDictionary(char*** dictionary, int dictionarySize); int main() { int dictionarySize; printf("Please enter dictionary size\n"); scanf("%d", &dictionarySize); char*** dictionary = MallocDic(dictionarySize); int i; for (i = 0; i < dictionarySize; i++) { char* inputWord = (char*)malloc(WORDLEN * sizeof(char)); char* inputDef = (char*)malloc(DEFLEN * sizeof(char)); if (inputWord == NULL || inputDef == NULL) { printf("Failed to allocate memory!\n"); exit(1); } printf("enter word : \n"); scanf("%s", inputWord); printf("enter definition : \n"); scanf("%s", inputDef); printf("word : %s ,def : %s\n", inputWord, inputDef); //dictionary[i] = MallocDicElement(inputWord, inputDef); //free(inputDef); free(inputWord); } printf("Print Dictionary : \n"); //PrintDictionary(dictionary, dictionarySize); } char*** MallocDic(int dictionarySize) { char*** p; p = (char***)malloc(dictionarySize * sizeof(char**)); return p; } char** MallocDicElement(char* word, char* definition) { char** p = (char**)malloc(KEYVALUE * sizeof(char*)); int i; for (i = 0; i < KEYVALUE; i++) { if (i == 0) { p[i] = (char*)malloc(WORDLEN * sizeof(char)); p[i] = word; } else { p[i] = (char*)malloc(DEFLEN * sizeof(char)); p[i] = definition; } } return p; } void PrintDictionary(char*** dictionary, int dictionarySize) { int i = 0, j = 0; for (i = 0; i < dictionarySize; i++) { for (j = 0; j < KEYVALUE; j++) { printf("word : %s\n", dictionary[i][0]); printf("definition : %s\n", dictionary[i][1]); } } }
错误原因分析
未初始化字典元素指针
你把核心赋值代码dictionary[i] = MallocDicElement(inputWord, inputDef);注释掉了,导致dictionary数组里的所有char**指针都是未初始化的野指针。当后续调用PrintDictionary访问这些野指针时,必然触发内存访问异常。MallocDicElement内存操作错误
函数内先为p[i]分配内存,随后直接将p[i]赋值为传入的word/definition指针:p[i] = (char*)malloc(WORDLEN * sizeof(char)); p[i] = word;这会导致两个问题:
- 刚分配的内存地址被覆盖,造成内存泄漏;
p[i]指向的是外部的inputWord/inputDef,当你在main里free(inputWord)后,p[i]就变成了悬空指针,后续访问时会触发内存异常。
打印函数冗余逻辑
PrintDictionary的内层j循环完全多余,每次循环都重复打印同一个单词和定义,没有意义。
修复后的完整代码
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h> #define WORDLEN 80 #define DEFLEN 200 #define KEYVALUE 2 char*** MallocDic(int dictionarySize); char** MallocDicElement(char* word, char* definition); void PrintDictionary(char*** dictionary, int dictionarySize); void FreeDictionary(char*** dictionary, int dictionarySize); int main() { int dictionarySize; printf("Please enter dictionary size\n"); scanf("%d", &dictionarySize); char*** dictionary = MallocDic(dictionarySize); if (dictionary == NULL) { printf("Failed to allocate dictionary!\n"); exit(1); } int i; for (i = 0; i < dictionarySize; i++) { char* inputWord = (char*)malloc(WORDLEN * sizeof(char)); char* inputDef = (char*)malloc(DEFLEN * sizeof(char)); if (inputWord == NULL || inputDef == NULL) { printf("Failed to allocate memory!\n"); FreeDictionary(dictionary, i); exit(1); } printf("enter word : \n"); scanf("%s", inputWord); printf("enter definition : \n"); scanf("%s", inputDef); printf("word : %s ,def : %s\n", inputWord, inputDef); // 恢复赋值逻辑 dictionary[i] = MallocDicElement(inputWord, inputDef); // 释放临时输入内存,因为内容已经复制到字典的内存中 free(inputDef); free(inputWord); } printf("Print Dictionary : \n"); PrintDictionary(dictionary, dictionarySize); // 释放字典内存,避免泄漏 FreeDictionary(dictionary, dictionarySize); } char*** MallocDic(int dictionarySize) { return (char***)malloc(dictionarySize * sizeof(char**)); } char** MallocDicElement(char* word, char* definition) { char** p = (char**)malloc(KEYVALUE * sizeof(char*)); if (p == NULL) return NULL; // 为单词分配内存并复制内容 p[0] = (char*)malloc(WORDLEN * sizeof(char)); if (p[0] != NULL) { strncpy(p[0], word, WORDLEN - 1); p[0][WORDLEN - 1] = '\0'; // 确保字符串终止 } // 为定义分配内存并复制内容 p[1] = (char*)malloc(DEFLEN * sizeof(char)); if (p[1] != NULL) { strncpy(p[1], definition, DEFLEN - 1); p[1][DEFLEN - 1] = '\0'; } return p; } void PrintDictionary(char*** dictionary, int dictionarySize) { for (int i = 0; i < dictionarySize; i++) { if (dictionary[i] != NULL) { printf("Word: %s\n", dictionary[i][0]); printf("Definition: %s\n", dictionary[i][1]); printf("------------------------\n"); } } } // 新增内存释放函数,避免内存泄漏 void FreeDictionary(char*** dictionary, int dictionarySize) { for (int i = 0; i < dictionarySize; i++) { if (dictionary[i] != NULL) { free(dictionary[i][0]); free(dictionary[i][1]); free(dictionary[i]); } } free(dictionary); }
修复说明
- 恢复了
dictionary[i] = MallocDicElement(...)的赋值逻辑,确保字典元素指针被正确初始化; - 修改
MallocDicElement,用strncpy将字符串内容复制到新分配的内存中,避免悬空指针和内存泄漏; - 新增
FreeDictionary函数,负责释放字典的所有内存,避免程序退出后残留内存泄漏; - 简化了
PrintDictionary的逻辑,去掉冗余的内层循环; - 增加了内存分配失败的判断,让程序更健壮。
内容的提问来源于stack exchange,提问作者Dan D
相关产品推荐
相关产品推荐

