Azurestar_Hu
2021-07-29 14:51
采纳率: 100%
浏览 34

引发了异常: 读取访问权限冲突。 **_Ptr_user** 是 0x0。

    背景

这是我尝试最大公共子序列时用到的一份代码,代码大量用到了指针,并且以DP和dfs作为解题的主要突破方向。

    使用环境

系统:64位 windows7 旗舰版 SP1

可视化编译工具:Visual Studio 2019 社区版 

    问题

我尝试一组数据,程序成功输出了我想要的结果,但是在通过图示标注的断点之后,爆出了题干的异常。 (这也是我最疑惑的其中一个点,因为以往从未见过顺利通过了return 0;的main语句还会出错的情况)即:

线程 0x2674 已退出,返回值为 0 (0x0)。

引发了异常: 读取访问权限冲突。

**_Ptr_user** 是 0x0。

    曾有的尝试

  我曾认为可能是dfs函数内大量声明string导致局部变量爆栈,于是添加了全局的BunkOfString的string组和STRScale的标记用来维护栈,并将dfs函数的string形参类型修改为引用,想要降低dfs函数对栈的负担,但是最后的结果仍旧一样,并无任何改良成功的迹象。因此我想知道,导致这份代码异常的原因到底是什么。

如果能够给我指一条方向就好了。

    下附图片

img

    下附代码(c++)


#pragma warning(disable:4996)
#include<cstdio>
#include<iostream>
#include<string>
#include<algorithm>
using std::string;

struct node {
    char val;
    bool isitmother;//mark the main node
    int rank;
    node* left;
    node* upright;
};
node BUNK[10000];
int num;
char val1[90], val2[90];
node* table[90][90];
int N1, N2;
string strlib[10000];
int strnum;
string BunkOfString[10000];
int STRScale;
void dfs(node* point, const string& str) {
    if (point->rank == 0) {//in one end of the dfs
        strlib[strnum].clear();
        int i = str.size() - 1;
        for (; i >= 0; i--) {
            strlib[strnum] += str[i];
        }
        strnum++;
        return;
    }
    if (point->isitmother == true) {//in the prime node
        string& stre = BunkOfString[STRScale++];
        stre = str + point->val;
        dfs(point->left, stre);
        stre.clear();
    }
    else {//in the subprime node
        while (point->isitmother != true) {
            dfs(point->upright, str);
            point = point->left;
        }
        dfs(point, str);
    }

}
int main() {
    //load
    char c;
    while (scanf("%c", &c), c == ' ');
    val1[(N1 = 0)++] = c;
    while (scanf("%c", &c), c != ' '&&c!='\n') {
        val1[N1++] = c;
    }
    while (scanf("%c", &c), c == ' ' || c == '\n');
    val2[(N2 = 0)++] = c;
    while (scanf("%c", &c) != EOF && c != ' '&&c!='\n') {
        val2[N2++] = c;
    }
    //initial
    BUNK[0].isitmother = true;
    BUNK[0].left = NULL;
    BUNK[0].upright = NULL;
    BUNK[0].val = '\0';
    BUNK[0].rank = 0;
    num = 1;
    for (int i = 0; i < 100; i++) {
        table[i][0] = BUNK;
        table[0][i] = BUNK;
    }
    for (int i = 0; i < N1; i++) {
        for (int j = 0; j < N2; j++) {
            if (val1[i] == val2[j]) {//inherit From triangle side
                node* oper = table[i + 1][j + 1] = &BUNK[num++];
                oper->isitmother = true;
                oper->left = table[i][j];
                oper->upright = oper;//self to self , easier to transmit
                oper->rank = table[i][j]->rank + 1;
                oper->val = val1[i];
            }
            else {//inherit from side two elements
                if (table[i + 1][j] == table[i][j + 1]) {//inherit directly
                    table[i + 1][j + 1] = table[i + 1][j];
                }
                else if(table[i+1][j]->rank==table[i][j+1]->rank) {//inherit from two
                    node* oper = table[i + 1][j + 1] = &BUNK[num++];
                    oper->isitmother = false;
                    oper->left = table[i + 1][j];
                    oper->upright = table[i][j + 1]->upright;//easier to transmit
                    oper->rank = table[i + 1][j]->rank;
                    oper->val = '\0';//nonsense actually
                }
                else {//inherit from one
                    if (table[i + 1][j]->rank < table[i][j + 1]->rank) {
                        table[i + 1][j + 1] = table[i][j + 1];
                    }
                    else {
                        table[i + 1][j + 1] = table[i + 1][j];
                    }
                }
            }
        }
    }
    string str0;
    strnum = 0;//no intialization in the begin of the cpp file
    STRScale = 0;
    dfs(table[N1][N2],str0);
    std::sort(strlib, strlib + strnum);
    for (int i = 0; i < strnum; i++) {
        std::cout << strlib[i] << "\n";
        strlib[i].clear();
    }
    return 0;
}


  • 点赞
  • 收藏

2条回答 默认 最新

  • Azurestar_Hu 2021-07-29 21:26
    已采纳

    谢谢大家的查看,解决方案已经找到了,貌似是使用string类导致内存爆了。事实上,将string组的大小减小到10的时候是不会异常的,而到100的时候又会异常。所以我猜测可能是string类的不定长特性导致的内存爆存,所以我停用string类,自己编写了一个定长的string类之后就没有异常抛出了。

    点赞 评论
  • qfl_sdu 2021-07-29 15:12

    while (scanf("%c", &c) != EOF && c != ' '&&c!='\n')这里 while (scanf("%c", &c) && c != ' '&&c!='\n'),其它地方应该还有错,目前没发现
    报的这个错误应该是使用了空指针,所以你在使用指针的地方先判断一下指针是否为0,如果为0,就直接退出

    点赞 评论

相关推荐 更多相似问题