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

使用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]);
        }
    }
}

错误原因分析

  1. 未初始化字典元素指针
    你把核心赋值代码dictionary[i] = MallocDicElement(inputWord, inputDef);注释掉了,导致dictionary数组里的所有char**指针都是未初始化的野指针。当后续调用PrintDictionary访问这些野指针时,必然触发内存访问异常。

  2. 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]就变成了悬空指针,后续访问时会触发内存异常。
  3. 打印函数冗余逻辑
    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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 02:01:05